1 // 2 // Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2018 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933 ); 934 935 %} 936 937 //----------DEFINITION BLOCK--------------------------------------------------- 938 // Define name --> value mappings to inform the ADLC of an integer valued name 939 // Current support includes integer values in the range [0, 0x7FFFFFFF] 940 // Format: 941 // int_def <name> ( <int_value>, <expression>); 942 // Generated Code in ad_<arch>.hpp 943 // #define <name> (<expression>) 944 // // value == <int_value> 945 // Generated code in ad_<arch>.cpp adlc_verification() 946 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947 // 948 definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961 %} 962 963 964 //----------SOURCE BLOCK------------------------------------------------------- 965 // This is a block of C++ code which provides values, functions, and 966 // definitions necessary in the rest of the architecture description. 967 source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979 %} 980 981 source %{ 982 983 // Should the Matcher clone shifts on addressing modes, expecting them 984 // to be subsumed into complex addressing expressions or compute them 985 // into registers? 986 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 987 return clone_base_plus_offset_address(m, mstack, address_visited); 988 } 989 990 void Compile::reshape_address(AddPNode* addp) { 991 } 992 993 // Optimize load-acquire. 994 // 995 // Check if acquire is unnecessary due to following operation that does 996 // acquire anyways. 997 // Walk the pattern: 998 // 999 // n: Load.acq 1000 // | 1001 // MemBarAcquire 1002 // | | 1003 // Proj(ctrl) Proj(mem) 1004 // | | 1005 // MemBarRelease/Volatile 1006 // 1007 bool followed_by_acquire(const Node *load) { 1008 assert(load->is_Load(), "So far implemented only for loads."); 1009 1010 // Find MemBarAcquire. 1011 const Node *mba = NULL; 1012 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1013 const Node *out = load->fast_out(i); 1014 if (out->Opcode() == Op_MemBarAcquire) { 1015 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1016 mba = out; 1017 break; 1018 } 1019 } 1020 if (!mba) return false; 1021 1022 // Find following MemBar node. 1023 // 1024 // The following node must be reachable by control AND memory 1025 // edge to assure no other operations are in between the two nodes. 1026 // 1027 // So first get the Proj node, mem_proj, to use it to iterate forward. 1028 Node *mem_proj = NULL; 1029 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1030 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1031 assert(mem_proj->is_Proj(), "only projections here"); 1032 ProjNode *proj = mem_proj->as_Proj(); 1033 if (proj->_con == TypeFunc::Memory && 1034 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1035 break; 1036 } 1037 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1038 1039 // Search MemBar behind Proj. If there are other memory operations 1040 // behind the Proj we lost. 1041 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1042 Node *x = mem_proj->fast_out(j); 1043 // Proj might have an edge to a store or load node which precedes the membar. 1044 if (x->is_Mem()) return false; 1045 1046 // On PPC64 release and volatile are implemented by an instruction 1047 // that also has acquire semantics. I.e. there is no need for an 1048 // acquire before these. 1049 int xop = x->Opcode(); 1050 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1051 // Make sure we're not missing Call/Phi/MergeMem by checking 1052 // control edges. The control edge must directly lead back 1053 // to the MemBarAcquire 1054 Node *ctrl_proj = x->in(0); 1055 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1056 return true; 1057 } 1058 } 1059 } 1060 1061 return false; 1062 } 1063 1064 #define __ _masm. 1065 1066 // Tertiary op of a LoadP or StoreP encoding. 1067 #define REGP_OP true 1068 1069 // **************************************************************************** 1070 1071 // REQUIRED FUNCTIONALITY 1072 1073 // !!!!! Special hack to get all type of calls to specify the byte offset 1074 // from the start of the call to the point where the return address 1075 // will point. 1076 1077 // PPC port: Removed use of lazy constant construct. 1078 1079 int MachCallStaticJavaNode::ret_addr_offset() { 1080 // It's only a single branch-and-link instruction. 1081 return 4; 1082 } 1083 1084 int MachCallDynamicJavaNode::ret_addr_offset() { 1085 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1086 // postalloc expanded calls if we use inline caches and do not update method data. 1087 if (UseInlineCaches) 1088 return 4; 1089 1090 int vtable_index = this->_vtable_index; 1091 if (vtable_index < 0) { 1092 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1093 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1094 return 12; 1095 } else { 1096 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1097 return 24; 1098 } 1099 } 1100 1101 int MachCallRuntimeNode::ret_addr_offset() { 1102 #if defined(ABI_ELFv2) 1103 return 28; 1104 #else 1105 return 40; 1106 #endif 1107 } 1108 1109 //============================================================================= 1110 1111 // condition code conversions 1112 1113 static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115 } 1116 1117 static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119 } 1120 1121 static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123 } 1124 1125 //============================================================================= 1126 1127 // Compute padding required for nodes which need alignment. The padding 1128 // is the number of bytes (not instructions) which will be inserted before 1129 // the instruction. The padding must match the size of a NOP instruction. 1130 1131 // Currently not used on this platform. 1132 1133 //============================================================================= 1134 1135 // Indicate if the safepoint node needs the polling page as an input. 1136 bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139 } 1140 1141 //============================================================================= 1142 1143 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1144 void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147 } 1148 1149 #ifndef PRODUCT 1150 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152 } 1153 #endif 1154 1155 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157 } 1158 1159 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161 } 1162 1163 //============================================================================= 1164 1165 void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168 } 1169 1170 static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173 } 1174 1175 //============================================================================= 1176 1177 %} // interrupt source 1178 1179 source_hpp %{ // Header information of the source block. 1180 1181 //-------------------------------------------------------------- 1182 //---< Used for optimization in Compile::Shorten_branches >--- 1183 //-------------------------------------------------------------- 1184 1185 class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204 }; 1205 1206 %} // end source_hpp 1207 1208 source %{ 1209 1210 // Emit a trampoline stub for a call to a target which is too far away. 1211 // 1212 // code sequences: 1213 // 1214 // call-site: 1215 // branch-and-link to <destination> or <trampoline stub> 1216 // 1217 // Related trampoline stub for this call-site in the stub section: 1218 // load the call target from the constant pool 1219 // branch via CTR (LR/link still points to the call-site above) 1220 1221 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226 } 1227 1228 //============================================================================= 1229 1230 // Emit an inline branch-and-link call and a related trampoline stub. 1231 // 1232 // code sequences: 1233 // 1234 // call-site: 1235 // branch-and-link to <destination> or <trampoline stub> 1236 // 1237 // Related trampoline stub for this call-site in the stub section: 1238 // load the call target from the constant pool 1239 // branch via CTR (LR/link still points to the call-site above) 1240 // 1241 1242 typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245 } EmitCallOffsets; 1246 1247 // Emit a branch-and-link instruction that branches to a trampoline. 1248 // - Remember the offset of the branch-and-link instruction. 1249 // - Add a relocation at the branch-and-link instruction. 1250 // - Emit a branch-and-link. 1251 // - Remember the return pc offset. 1252 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281 } 1282 1283 //============================================================================= 1284 1285 // Factory for creating loadConL* nodes for large/small constant pool. 1286 1287 static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293 } 1294 1295 //============================================================================= 1296 1297 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298 int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300 } 1301 1302 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317 } 1318 1319 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322 } 1323 1324 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326 } 1327 1328 #ifndef PRODUCT 1329 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331 } 1332 #endif 1333 1334 //============================================================================= 1335 1336 #ifndef PRODUCT 1337 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350 } 1351 #endif 1352 1353 // Macro used instead of the common __ to emulate the pipes of PPC. 1354 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356 // still no scheduling of this code is possible, the micro scheduler is aware of the 1357 // code and can update its internal data. The following mechanism is used to achieve this: 1358 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1359 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360 #if 0 // TODO: PPC port 1361 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368 #else 1369 #define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372 #define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374 #define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376 #endif 1377 1378 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505 #if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514 #endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521 } 1522 #undef ___ 1523 #undef ___stop 1524 #undef ___advance 1525 1526 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529 } 1530 1531 int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534 } 1535 1536 //============================================================================= 1537 1538 #ifndef PRODUCT 1539 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549 } 1550 #endif 1551 1552 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594 } 1595 1596 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599 } 1600 1601 int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604 } 1605 1606 const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608 } 1609 1610 // This method seems to be obsolete. It is declared in machnode.hpp 1611 // and defined in all *.ad files, but it is never called. Should we 1612 // get rid of it? 1613 int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616 } 1617 1618 #if 0 // TODO: PPC port 1619 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626 } 1627 1628 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634 } 1635 1636 #ifndef PRODUCT 1637 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639 } 1640 #endif 1641 1642 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644 } 1645 #endif // PPC port 1646 1647 // ============================================================================= 1648 1649 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650 // rc_stack. 1651 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653 static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673 } 1674 1675 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695 #ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702 #endif 1703 return 4; // size 1704 } 1705 1706 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821 #ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829 #endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867 #ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871 #endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910 } 1911 1912 #ifndef PRODUCT 1913 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918 } 1919 #endif 1920 1921 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923 } 1924 1925 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927 } 1928 1929 #if 0 // TODO: PPC port 1930 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931 #ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933 #endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022 } 2023 #endif // PPC port 2024 2025 #ifndef PRODUCT 2026 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028 } 2029 #endif 2030 2031 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037 } 2038 2039 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041 } 2042 2043 #ifndef PRODUCT 2044 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049 } 2050 #endif 2051 2052 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063 } 2064 2065 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068 } 2069 2070 #ifndef PRODUCT 2071 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074 } 2075 #endif 2076 2077 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118 } 2119 2120 #if 0 // TODO: PPC port 2121 // Optimize UEP code on z (save a load_const() call in main path). 2122 int MachUEPNode::ep_offset() { 2123 return 0; 2124 } 2125 #endif 2126 2127 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130 } 2131 2132 //============================================================================= 2133 2134 %} // interrupt source 2135 2136 source_hpp %{ // Header information of the source block. 2137 2138 class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155 }; 2156 2157 %} // end source_hpp 2158 2159 source %{ 2160 2161 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174 } 2175 2176 // The deopt_handler is like the exception handler, but it calls to 2177 // the deoptimization blob instead of jumping to the exception blob. 2178 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191 } 2192 2193 //============================================================================= 2194 2195 // Use a frame slots bias for frameless methods if accessing the stack. 2196 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201 } 2202 2203 const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 case Op_StrIndexOfChar: 2232 return SpecialStringIndexOf; 2233 case Op_AddVB: 2234 case Op_AddVS: 2235 case Op_AddVI: 2236 case Op_AddVF: 2237 case Op_AddVD: 2238 case Op_SubVB: 2239 case Op_SubVS: 2240 case Op_SubVI: 2241 case Op_SubVF: 2242 case Op_SubVD: 2243 case Op_MulVS: 2244 case Op_MulVF: 2245 case Op_MulVD: 2246 case Op_DivVF: 2247 case Op_DivVD: 2248 case Op_AbsVF: 2249 case Op_AbsVD: 2250 case Op_NegVF: 2251 case Op_NegVD: 2252 case Op_SqrtVF: 2253 case Op_SqrtVD: 2254 case Op_AddVL: 2255 case Op_SubVL: 2256 case Op_MulVI: 2257 return SuperwordUseVSX; 2258 case Op_PopCountVI: 2259 return (SuperwordUseVSX && UsePopCountInstruction); 2260 case Op_FmaVF: 2261 case Op_FmaVD: 2262 return (SuperwordUseVSX && UseFMA); 2263 case Op_Digit: 2264 case Op_LowerCase: 2265 case Op_UpperCase: 2266 case Op_Whitespace: 2267 return UseCharacterCompareIntrinsics; 2268 } 2269 2270 return true; // Per default match rules are supported. 2271 } 2272 2273 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2274 2275 // TODO 2276 // identify extra cases that we might want to provide match rules for 2277 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2278 bool ret_value = match_rule_supported(opcode); 2279 // Add rules here. 2280 2281 return ret_value; // Per default match rules are supported. 2282 } 2283 2284 const bool Matcher::has_predicated_vectors(void) { 2285 return false; 2286 } 2287 2288 const int Matcher::float_pressure(int default_pressure_threshold) { 2289 return default_pressure_threshold; 2290 } 2291 2292 int Matcher::regnum_to_fpu_offset(int regnum) { 2293 // No user for this method? 2294 Unimplemented(); 2295 return 999; 2296 } 2297 2298 const bool Matcher::convL2FSupported(void) { 2299 // fcfids can do the conversion (>= Power7). 2300 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2301 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2302 } 2303 2304 // Vector width in bytes. 2305 const int Matcher::vector_width_in_bytes(BasicType bt) { 2306 if (SuperwordUseVSX) { 2307 assert(MaxVectorSize == 16, ""); 2308 return 16; 2309 } else { 2310 assert(MaxVectorSize == 8, ""); 2311 return 8; 2312 } 2313 } 2314 2315 // Vector ideal reg. 2316 const uint Matcher::vector_ideal_reg(int size) { 2317 if (SuperwordUseVSX) { 2318 assert(MaxVectorSize == 16 && size == 16, ""); 2319 return Op_VecX; 2320 } else { 2321 assert(MaxVectorSize == 8 && size == 8, ""); 2322 return Op_RegL; 2323 } 2324 } 2325 2326 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2327 fatal("vector shift is not supported"); 2328 return Node::NotAMachineReg; 2329 } 2330 2331 // Limits on vector size (number of elements) loaded into vector. 2332 const int Matcher::max_vector_size(const BasicType bt) { 2333 assert(is_java_primitive(bt), "only primitive type vectors"); 2334 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2335 } 2336 2337 const int Matcher::min_vector_size(const BasicType bt) { 2338 return max_vector_size(bt); // Same as max. 2339 } 2340 2341 // PPC implementation uses VSX load/store instructions (if 2342 // SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2343 const bool Matcher::misaligned_vectors_ok() { 2344 return false; 2345 } 2346 2347 // PPC AES support not yet implemented 2348 const bool Matcher::pass_original_key_for_aes() { 2349 return false; 2350 } 2351 2352 // RETURNS: whether this branch offset is short enough that a short 2353 // branch can be used. 2354 // 2355 // If the platform does not provide any short branch variants, then 2356 // this method should return `false' for offset 0. 2357 // 2358 // `Compile::Fill_buffer' will decide on basis of this information 2359 // whether to do the pass `Compile::Shorten_branches' at all. 2360 // 2361 // And `Compile::Shorten_branches' will decide on basis of this 2362 // information whether to replace particular branch sites by short 2363 // ones. 2364 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2365 // Is the offset within the range of a ppc64 pc relative branch? 2366 bool b; 2367 2368 const int safety_zone = 3 * BytesPerInstWord; 2369 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2370 29 - 16 + 1 + 2); 2371 return b; 2372 } 2373 2374 const bool Matcher::isSimpleConstant64(jlong value) { 2375 // Probably always true, even if a temp register is required. 2376 return true; 2377 } 2378 /* TODO: PPC port 2379 // Make a new machine dependent decode node (with its operands). 2380 MachTypeNode *Matcher::make_decode_node() { 2381 assert(CompressedOops::base() == NULL && CompressedOops::shift() == 0, 2382 "This method is only implemented for unscaled cOops mode so far"); 2383 MachTypeNode *decode = new decodeN_unscaledNode(); 2384 decode->set_opnd_array(0, new iRegPdstOper()); 2385 decode->set_opnd_array(1, new iRegNsrcOper()); 2386 return decode; 2387 } 2388 */ 2389 2390 // false => size gets scaled to BytesPerLong, ok. 2391 const bool Matcher::init_array_count_is_in_bytes = false; 2392 2393 // Use conditional move (CMOVL) on Power7. 2394 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2395 2396 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2397 // fsel doesn't accept a condition register as input, so this would be slightly different. 2398 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2399 2400 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2401 const bool Matcher::require_postalloc_expand = true; 2402 2403 // Do we need to mask the count passed to shift instructions or does 2404 // the cpu only look at the lower 5/6 bits anyway? 2405 // PowerPC requires masked shift counts. 2406 const bool Matcher::need_masked_shift_count = true; 2407 2408 // This affects two different things: 2409 // - how Decode nodes are matched 2410 // - how ImplicitNullCheck opportunities are recognized 2411 // If true, the matcher will try to remove all Decodes and match them 2412 // (as operands) into nodes. NullChecks are not prepared to deal with 2413 // Decodes by final_graph_reshaping(). 2414 // If false, final_graph_reshaping() forces the decode behind the Cmp 2415 // for a NullCheck. The matcher matches the Decode node into a register. 2416 // Implicit_null_check optimization moves the Decode along with the 2417 // memory operation back up before the NullCheck. 2418 bool Matcher::narrow_oop_use_complex_address() { 2419 // TODO: PPC port if (MatchDecodeNodes) return true; 2420 return false; 2421 } 2422 2423 bool Matcher::narrow_klass_use_complex_address() { 2424 NOT_LP64(ShouldNotCallThis()); 2425 assert(UseCompressedClassPointers, "only for compressed klass code"); 2426 // TODO: PPC port if (MatchDecodeNodes) return true; 2427 return false; 2428 } 2429 2430 bool Matcher::const_oop_prefer_decode() { 2431 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2432 return CompressedOops::base() == NULL; 2433 } 2434 2435 bool Matcher::const_klass_prefer_decode() { 2436 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2437 return CompressedKlassPointers::base() == NULL; 2438 } 2439 2440 // Is it better to copy float constants, or load them directly from memory? 2441 // Intel can load a float constant from a direct address, requiring no 2442 // extra registers. Most RISCs will have to materialize an address into a 2443 // register first, so they would do better to copy the constant from stack. 2444 const bool Matcher::rematerialize_float_constants = false; 2445 2446 // If CPU can load and store mis-aligned doubles directly then no fixup is 2447 // needed. Else we split the double into 2 integer pieces and move it 2448 // piece-by-piece. Only happens when passing doubles into C code as the 2449 // Java calling convention forces doubles to be aligned. 2450 const bool Matcher::misaligned_doubles_ok = true; 2451 2452 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2453 Unimplemented(); 2454 } 2455 2456 // Advertise here if the CPU requires explicit rounding operations 2457 // to implement the UseStrictFP mode. 2458 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2459 2460 // Do floats take an entire double register or just half? 2461 // 2462 // A float occupies a ppc64 double register. For the allocator, a 2463 // ppc64 double register appears as a pair of float registers. 2464 bool Matcher::float_in_double() { return true; } 2465 2466 // Do ints take an entire long register or just half? 2467 // The relevant question is how the int is callee-saved: 2468 // the whole long is written but de-opt'ing will have to extract 2469 // the relevant 32 bits. 2470 const bool Matcher::int_in_long = true; 2471 2472 // Constants for c2c and c calling conventions. 2473 2474 const MachRegisterNumbers iarg_reg[8] = { 2475 R3_num, R4_num, R5_num, R6_num, 2476 R7_num, R8_num, R9_num, R10_num 2477 }; 2478 2479 const MachRegisterNumbers farg_reg[13] = { 2480 F1_num, F2_num, F3_num, F4_num, 2481 F5_num, F6_num, F7_num, F8_num, 2482 F9_num, F10_num, F11_num, F12_num, 2483 F13_num 2484 }; 2485 2486 const MachRegisterNumbers vsarg_reg[64] = { 2487 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2488 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2489 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2490 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2491 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2492 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2493 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2494 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2495 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2496 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2497 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2498 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2499 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2500 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2501 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2502 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2503 }; 2504 2505 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2506 2507 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2508 2509 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2510 2511 // Return whether or not this register is ever used as an argument. This 2512 // function is used on startup to build the trampoline stubs in generateOptoStub. 2513 // Registers not mentioned will be killed by the VM call in the trampoline, and 2514 // arguments in those registers not be available to the callee. 2515 bool Matcher::can_be_java_arg(int reg) { 2516 // We return true for all registers contained in iarg_reg[] and 2517 // farg_reg[] and their virtual halves. 2518 // We must include the virtual halves in order to get STDs and LDs 2519 // instead of STWs and LWs in the trampoline stubs. 2520 2521 if ( reg == R3_num || reg == R3_H_num 2522 || reg == R4_num || reg == R4_H_num 2523 || reg == R5_num || reg == R5_H_num 2524 || reg == R6_num || reg == R6_H_num 2525 || reg == R7_num || reg == R7_H_num 2526 || reg == R8_num || reg == R8_H_num 2527 || reg == R9_num || reg == R9_H_num 2528 || reg == R10_num || reg == R10_H_num) 2529 return true; 2530 2531 if ( reg == F1_num || reg == F1_H_num 2532 || reg == F2_num || reg == F2_H_num 2533 || reg == F3_num || reg == F3_H_num 2534 || reg == F4_num || reg == F4_H_num 2535 || reg == F5_num || reg == F5_H_num 2536 || reg == F6_num || reg == F6_H_num 2537 || reg == F7_num || reg == F7_H_num 2538 || reg == F8_num || reg == F8_H_num 2539 || reg == F9_num || reg == F9_H_num 2540 || reg == F10_num || reg == F10_H_num 2541 || reg == F11_num || reg == F11_H_num 2542 || reg == F12_num || reg == F12_H_num 2543 || reg == F13_num || reg == F13_H_num) 2544 return true; 2545 2546 return false; 2547 } 2548 2549 bool Matcher::is_spillable_arg(int reg) { 2550 return can_be_java_arg(reg); 2551 } 2552 2553 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2554 return false; 2555 } 2556 2557 // Register for DIVI projection of divmodI. 2558 RegMask Matcher::divI_proj_mask() { 2559 ShouldNotReachHere(); 2560 return RegMask(); 2561 } 2562 2563 // Register for MODI projection of divmodI. 2564 RegMask Matcher::modI_proj_mask() { 2565 ShouldNotReachHere(); 2566 return RegMask(); 2567 } 2568 2569 // Register for DIVL projection of divmodL. 2570 RegMask Matcher::divL_proj_mask() { 2571 ShouldNotReachHere(); 2572 return RegMask(); 2573 } 2574 2575 // Register for MODL projection of divmodL. 2576 RegMask Matcher::modL_proj_mask() { 2577 ShouldNotReachHere(); 2578 return RegMask(); 2579 } 2580 2581 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2582 return RegMask(); 2583 } 2584 2585 const bool Matcher::convi2l_type_required = true; 2586 2587 %} 2588 2589 //----------ENCODING BLOCK----------------------------------------------------- 2590 // This block specifies the encoding classes used by the compiler to output 2591 // byte streams. Encoding classes are parameterized macros used by 2592 // Machine Instruction Nodes in order to generate the bit encoding of the 2593 // instruction. Operands specify their base encoding interface with the 2594 // interface keyword. There are currently supported four interfaces, 2595 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2596 // operand to generate a function which returns its register number when 2597 // queried. CONST_INTER causes an operand to generate a function which 2598 // returns the value of the constant when queried. MEMORY_INTER causes an 2599 // operand to generate four functions which return the Base Register, the 2600 // Index Register, the Scale Value, and the Offset Value of the operand when 2601 // queried. COND_INTER causes an operand to generate six functions which 2602 // return the encoding code (ie - encoding bits for the instruction) 2603 // associated with each basic boolean condition for a conditional instruction. 2604 // 2605 // Instructions specify two basic values for encoding. Again, a function 2606 // is available to check if the constant displacement is an oop. They use the 2607 // ins_encode keyword to specify their encoding classes (which must be 2608 // a sequence of enc_class names, and their parameters, specified in 2609 // the encoding block), and they use the 2610 // opcode keyword to specify, in order, their primary, secondary, and 2611 // tertiary opcode. Only the opcode sections which a particular instruction 2612 // needs for encoding need to be specified. 2613 encode %{ 2614 enc_class enc_unimplemented %{ 2615 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2616 MacroAssembler _masm(&cbuf); 2617 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2618 %} 2619 2620 enc_class enc_untested %{ 2621 #ifdef ASSERT 2622 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2623 MacroAssembler _masm(&cbuf); 2624 __ untested("Untested mach node encoding in AD file."); 2625 #else 2626 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2627 #endif 2628 %} 2629 2630 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2631 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2632 MacroAssembler _masm(&cbuf); 2633 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2634 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2635 %} 2636 2637 // Load acquire. 2638 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2639 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2640 MacroAssembler _masm(&cbuf); 2641 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2642 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2643 __ twi_0($dst$$Register); 2644 __ isync(); 2645 %} 2646 2647 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2648 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2649 2650 MacroAssembler _masm(&cbuf); 2651 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2652 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2653 %} 2654 2655 // Load acquire. 2656 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2657 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2658 2659 MacroAssembler _masm(&cbuf); 2660 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2661 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2662 __ twi_0($dst$$Register); 2663 __ isync(); 2664 %} 2665 2666 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2667 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2668 2669 MacroAssembler _masm(&cbuf); 2670 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2671 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2672 %} 2673 2674 // Load acquire. 2675 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2676 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2677 2678 MacroAssembler _masm(&cbuf); 2679 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2680 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2681 __ twi_0($dst$$Register); 2682 __ isync(); 2683 %} 2684 2685 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2686 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2687 MacroAssembler _masm(&cbuf); 2688 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2689 // Operand 'ds' requires 4-alignment. 2690 assert((Idisp & 0x3) == 0, "unaligned offset"); 2691 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2692 %} 2693 2694 // Load acquire. 2695 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2696 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2697 MacroAssembler _masm(&cbuf); 2698 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2699 // Operand 'ds' requires 4-alignment. 2700 assert((Idisp & 0x3) == 0, "unaligned offset"); 2701 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2702 __ twi_0($dst$$Register); 2703 __ isync(); 2704 %} 2705 2706 enc_class enc_lfd(RegF dst, memory mem) %{ 2707 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2708 MacroAssembler _masm(&cbuf); 2709 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2710 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2711 %} 2712 2713 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2714 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2715 2716 MacroAssembler _masm(&cbuf); 2717 int toc_offset = 0; 2718 2719 address const_toc_addr; 2720 // Create a non-oop constant, no relocation needed. 2721 // If it is an IC, it has a virtual_call_Relocation. 2722 const_toc_addr = __ long_constant((jlong)$src$$constant); 2723 if (const_toc_addr == NULL) { 2724 ciEnv::current()->record_out_of_memory_failure(); 2725 return; 2726 } 2727 2728 // Get the constant's TOC offset. 2729 toc_offset = __ offset_to_method_toc(const_toc_addr); 2730 2731 // Keep the current instruction offset in mind. 2732 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2733 2734 __ ld($dst$$Register, toc_offset, $toc$$Register); 2735 %} 2736 2737 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2738 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2739 2740 MacroAssembler _masm(&cbuf); 2741 2742 if (!ra_->C->in_scratch_emit_size()) { 2743 address const_toc_addr; 2744 // Create a non-oop constant, no relocation needed. 2745 // If it is an IC, it has a virtual_call_Relocation. 2746 const_toc_addr = __ long_constant((jlong)$src$$constant); 2747 if (const_toc_addr == NULL) { 2748 ciEnv::current()->record_out_of_memory_failure(); 2749 return; 2750 } 2751 2752 // Get the constant's TOC offset. 2753 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2754 // Store the toc offset of the constant. 2755 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2756 2757 // Also keep the current instruction offset in mind. 2758 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2759 } 2760 2761 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2762 %} 2763 2764 %} // encode 2765 2766 source %{ 2767 2768 typedef struct { 2769 loadConL_hiNode *_large_hi; 2770 loadConL_loNode *_large_lo; 2771 loadConLNode *_small; 2772 MachNode *_last; 2773 } loadConLNodesTuple; 2774 2775 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2776 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2777 loadConLNodesTuple nodes; 2778 2779 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2780 if (large_constant_pool) { 2781 // Create new nodes. 2782 loadConL_hiNode *m1 = new loadConL_hiNode(); 2783 loadConL_loNode *m2 = new loadConL_loNode(); 2784 2785 // inputs for new nodes 2786 m1->add_req(NULL, toc); 2787 m2->add_req(NULL, m1); 2788 2789 // operands for new nodes 2790 m1->_opnds[0] = new iRegLdstOper(); // dst 2791 m1->_opnds[1] = immSrc; // src 2792 m1->_opnds[2] = new iRegPdstOper(); // toc 2793 m2->_opnds[0] = new iRegLdstOper(); // dst 2794 m2->_opnds[1] = immSrc; // src 2795 m2->_opnds[2] = new iRegLdstOper(); // base 2796 2797 // Initialize ins_attrib TOC fields. 2798 m1->_const_toc_offset = -1; 2799 m2->_const_toc_offset_hi_node = m1; 2800 2801 // Initialize ins_attrib instruction offset. 2802 m1->_cbuf_insts_offset = -1; 2803 2804 // register allocation for new nodes 2805 ra_->set_pair(m1->_idx, reg_second, reg_first); 2806 ra_->set_pair(m2->_idx, reg_second, reg_first); 2807 2808 // Create result. 2809 nodes._large_hi = m1; 2810 nodes._large_lo = m2; 2811 nodes._small = NULL; 2812 nodes._last = nodes._large_lo; 2813 assert(m2->bottom_type()->isa_long(), "must be long"); 2814 } else { 2815 loadConLNode *m2 = new loadConLNode(); 2816 2817 // inputs for new nodes 2818 m2->add_req(NULL, toc); 2819 2820 // operands for new nodes 2821 m2->_opnds[0] = new iRegLdstOper(); // dst 2822 m2->_opnds[1] = immSrc; // src 2823 m2->_opnds[2] = new iRegPdstOper(); // toc 2824 2825 // Initialize ins_attrib instruction offset. 2826 m2->_cbuf_insts_offset = -1; 2827 2828 // register allocation for new nodes 2829 ra_->set_pair(m2->_idx, reg_second, reg_first); 2830 2831 // Create result. 2832 nodes._large_hi = NULL; 2833 nodes._large_lo = NULL; 2834 nodes._small = m2; 2835 nodes._last = nodes._small; 2836 assert(m2->bottom_type()->isa_long(), "must be long"); 2837 } 2838 2839 return nodes; 2840 } 2841 2842 typedef struct { 2843 loadConL_hiNode *_large_hi; 2844 loadConL_loNode *_large_lo; 2845 mtvsrdNode *_moved; 2846 xxspltdNode *_replicated; 2847 loadConLNode *_small; 2848 MachNode *_last; 2849 } loadConLReplicatedNodesTuple; 2850 2851 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2852 vecXOper *dst, immI_0Oper *zero, 2853 OptoReg::Name reg_second, OptoReg::Name reg_first, 2854 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2855 loadConLReplicatedNodesTuple nodes; 2856 2857 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2858 if (large_constant_pool) { 2859 // Create new nodes. 2860 loadConL_hiNode *m1 = new loadConL_hiNode(); 2861 loadConL_loNode *m2 = new loadConL_loNode(); 2862 mtvsrdNode *m3 = new mtvsrdNode(); 2863 xxspltdNode *m4 = new xxspltdNode(); 2864 2865 // inputs for new nodes 2866 m1->add_req(NULL, toc); 2867 m2->add_req(NULL, m1); 2868 m3->add_req(NULL, m2); 2869 m4->add_req(NULL, m3); 2870 2871 // operands for new nodes 2872 m1->_opnds[0] = new iRegLdstOper(); // dst 2873 m1->_opnds[1] = immSrc; // src 2874 m1->_opnds[2] = new iRegPdstOper(); // toc 2875 2876 m2->_opnds[0] = new iRegLdstOper(); // dst 2877 m2->_opnds[1] = immSrc; // src 2878 m2->_opnds[2] = new iRegLdstOper(); // base 2879 2880 m3->_opnds[0] = new vecXOper(); // dst 2881 m3->_opnds[1] = new iRegLdstOper(); // src 2882 2883 m4->_opnds[0] = new vecXOper(); // dst 2884 m4->_opnds[1] = new vecXOper(); // src 2885 m4->_opnds[2] = zero; 2886 2887 // Initialize ins_attrib TOC fields. 2888 m1->_const_toc_offset = -1; 2889 m2->_const_toc_offset_hi_node = m1; 2890 2891 // Initialize ins_attrib instruction offset. 2892 m1->_cbuf_insts_offset = -1; 2893 2894 // register allocation for new nodes 2895 ra_->set_pair(m1->_idx, reg_second, reg_first); 2896 ra_->set_pair(m2->_idx, reg_second, reg_first); 2897 ra_->set1(m3->_idx, reg_second); 2898 ra_->set2(m3->_idx, reg_vec_first); 2899 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2900 2901 // Create result. 2902 nodes._large_hi = m1; 2903 nodes._large_lo = m2; 2904 nodes._moved = m3; 2905 nodes._replicated = m4; 2906 nodes._small = NULL; 2907 nodes._last = nodes._replicated; 2908 assert(m2->bottom_type()->isa_long(), "must be long"); 2909 } else { 2910 loadConLNode *m2 = new loadConLNode(); 2911 mtvsrdNode *m3 = new mtvsrdNode(); 2912 xxspltdNode *m4 = new xxspltdNode(); 2913 2914 // inputs for new nodes 2915 m2->add_req(NULL, toc); 2916 2917 // operands for new nodes 2918 m2->_opnds[0] = new iRegLdstOper(); // dst 2919 m2->_opnds[1] = immSrc; // src 2920 m2->_opnds[2] = new iRegPdstOper(); // toc 2921 2922 m3->_opnds[0] = new vecXOper(); // dst 2923 m3->_opnds[1] = new iRegLdstOper(); // src 2924 2925 m4->_opnds[0] = new vecXOper(); // dst 2926 m4->_opnds[1] = new vecXOper(); // src 2927 m4->_opnds[2] = zero; 2928 2929 // Initialize ins_attrib instruction offset. 2930 m2->_cbuf_insts_offset = -1; 2931 ra_->set1(m3->_idx, reg_second); 2932 ra_->set2(m3->_idx, reg_vec_first); 2933 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2934 2935 // register allocation for new nodes 2936 ra_->set_pair(m2->_idx, reg_second, reg_first); 2937 2938 // Create result. 2939 nodes._large_hi = NULL; 2940 nodes._large_lo = NULL; 2941 nodes._small = m2; 2942 nodes._moved = m3; 2943 nodes._replicated = m4; 2944 nodes._last = nodes._replicated; 2945 assert(m2->bottom_type()->isa_long(), "must be long"); 2946 } 2947 2948 return nodes; 2949 } 2950 2951 %} // source 2952 2953 encode %{ 2954 // Postalloc expand emitter for loading a long constant from the method's TOC. 2955 // Enc_class needed as consttanttablebase is not supported by postalloc 2956 // expand. 2957 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2958 // Create new nodes. 2959 loadConLNodesTuple loadConLNodes = 2960 loadConLNodesTuple_create(ra_, n_toc, op_src, 2961 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2962 2963 // Push new nodes. 2964 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2965 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2966 2967 // some asserts 2968 assert(nodes->length() >= 1, "must have created at least 1 node"); 2969 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2970 %} 2971 2972 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2973 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2974 2975 MacroAssembler _masm(&cbuf); 2976 int toc_offset = 0; 2977 2978 intptr_t val = $src$$constant; 2979 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2980 address const_toc_addr; 2981 if (constant_reloc == relocInfo::oop_type) { 2982 // Create an oop constant and a corresponding relocation. 2983 AddressLiteral a = __ allocate_oop_address((jobject)val); 2984 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2985 __ relocate(a.rspec()); 2986 } else if (constant_reloc == relocInfo::metadata_type) { 2987 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2988 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2989 __ relocate(a.rspec()); 2990 } else { 2991 // Create a non-oop constant, no relocation needed. 2992 const_toc_addr = __ long_constant((jlong)$src$$constant); 2993 } 2994 2995 if (const_toc_addr == NULL) { 2996 ciEnv::current()->record_out_of_memory_failure(); 2997 return; 2998 } 2999 // Get the constant's TOC offset. 3000 toc_offset = __ offset_to_method_toc(const_toc_addr); 3001 3002 __ ld($dst$$Register, toc_offset, $toc$$Register); 3003 %} 3004 3005 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 3006 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 3007 3008 MacroAssembler _masm(&cbuf); 3009 if (!ra_->C->in_scratch_emit_size()) { 3010 intptr_t val = $src$$constant; 3011 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 3012 address const_toc_addr; 3013 if (constant_reloc == relocInfo::oop_type) { 3014 // Create an oop constant and a corresponding relocation. 3015 AddressLiteral a = __ allocate_oop_address((jobject)val); 3016 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3017 __ relocate(a.rspec()); 3018 } else if (constant_reloc == relocInfo::metadata_type) { 3019 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 3020 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 3021 __ relocate(a.rspec()); 3022 } else { // non-oop pointers, e.g. card mark base, heap top 3023 // Create a non-oop constant, no relocation needed. 3024 const_toc_addr = __ long_constant((jlong)$src$$constant); 3025 } 3026 3027 if (const_toc_addr == NULL) { 3028 ciEnv::current()->record_out_of_memory_failure(); 3029 return; 3030 } 3031 // Get the constant's TOC offset. 3032 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3033 // Store the toc offset of the constant. 3034 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3035 } 3036 3037 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3038 %} 3039 3040 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3041 // Enc_class needed as consttanttablebase is not supported by postalloc 3042 // expand. 3043 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3044 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3045 if (large_constant_pool) { 3046 // Create new nodes. 3047 loadConP_hiNode *m1 = new loadConP_hiNode(); 3048 loadConP_loNode *m2 = new loadConP_loNode(); 3049 3050 // inputs for new nodes 3051 m1->add_req(NULL, n_toc); 3052 m2->add_req(NULL, m1); 3053 3054 // operands for new nodes 3055 m1->_opnds[0] = new iRegPdstOper(); // dst 3056 m1->_opnds[1] = op_src; // src 3057 m1->_opnds[2] = new iRegPdstOper(); // toc 3058 m2->_opnds[0] = new iRegPdstOper(); // dst 3059 m2->_opnds[1] = op_src; // src 3060 m2->_opnds[2] = new iRegLdstOper(); // base 3061 3062 // Initialize ins_attrib TOC fields. 3063 m1->_const_toc_offset = -1; 3064 m2->_const_toc_offset_hi_node = m1; 3065 3066 // Register allocation for new nodes. 3067 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3068 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3069 3070 nodes->push(m1); 3071 nodes->push(m2); 3072 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3073 } else { 3074 loadConPNode *m2 = new loadConPNode(); 3075 3076 // inputs for new nodes 3077 m2->add_req(NULL, n_toc); 3078 3079 // operands for new nodes 3080 m2->_opnds[0] = new iRegPdstOper(); // dst 3081 m2->_opnds[1] = op_src; // src 3082 m2->_opnds[2] = new iRegPdstOper(); // toc 3083 3084 // Register allocation for new nodes. 3085 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3086 3087 nodes->push(m2); 3088 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3089 } 3090 %} 3091 3092 // Enc_class needed as consttanttablebase is not supported by postalloc 3093 // expand. 3094 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3095 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3096 3097 MachNode *m2; 3098 if (large_constant_pool) { 3099 m2 = new loadConFCompNode(); 3100 } else { 3101 m2 = new loadConFNode(); 3102 } 3103 // inputs for new nodes 3104 m2->add_req(NULL, n_toc); 3105 3106 // operands for new nodes 3107 m2->_opnds[0] = op_dst; 3108 m2->_opnds[1] = op_src; 3109 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3110 3111 // register allocation for new nodes 3112 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3113 nodes->push(m2); 3114 %} 3115 3116 // Enc_class needed as consttanttablebase is not supported by postalloc 3117 // expand. 3118 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3119 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3120 3121 MachNode *m2; 3122 if (large_constant_pool) { 3123 m2 = new loadConDCompNode(); 3124 } else { 3125 m2 = new loadConDNode(); 3126 } 3127 // inputs for new nodes 3128 m2->add_req(NULL, n_toc); 3129 3130 // operands for new nodes 3131 m2->_opnds[0] = op_dst; 3132 m2->_opnds[1] = op_src; 3133 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3134 3135 // register allocation for new nodes 3136 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3137 nodes->push(m2); 3138 %} 3139 3140 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3141 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3142 MacroAssembler _masm(&cbuf); 3143 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3144 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3145 %} 3146 3147 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3148 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3149 MacroAssembler _masm(&cbuf); 3150 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3151 // Operand 'ds' requires 4-alignment. 3152 assert((Idisp & 0x3) == 0, "unaligned offset"); 3153 __ std($src$$Register, Idisp, $mem$$base$$Register); 3154 %} 3155 3156 enc_class enc_stfs(RegF src, memory mem) %{ 3157 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3158 MacroAssembler _masm(&cbuf); 3159 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3160 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3161 %} 3162 3163 enc_class enc_stfd(RegF src, memory mem) %{ 3164 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3165 MacroAssembler _masm(&cbuf); 3166 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3167 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3168 %} 3169 3170 // Use release_store for card-marking to ensure that previous 3171 // oop-stores are visible before the card-mark change. 3172 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3173 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3174 // FIXME: Implement this as a cmove and use a fixed condition code 3175 // register which is written on every transition to compiled code, 3176 // e.g. in call-stub and when returning from runtime stubs. 3177 // 3178 // Proposed code sequence for the cmove implementation: 3179 // 3180 // Label skip_release; 3181 // __ beq(CCRfixed, skip_release); 3182 // __ release(); 3183 // __ bind(skip_release); 3184 // __ stb(card mark); 3185 3186 MacroAssembler _masm(&cbuf); 3187 Label skip_storestore; 3188 3189 #if 0 // TODO: PPC port 3190 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3191 // StoreStore barrier conditionally. 3192 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3193 __ cmpwi($crx$$CondRegister, R0, 0); 3194 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3195 #endif 3196 __ li(R0, 0); 3197 __ membar(Assembler::StoreStore); 3198 #if 0 // TODO: PPC port 3199 __ bind(skip_storestore); 3200 #endif 3201 3202 // Do the store. 3203 if ($mem$$index == 0) { 3204 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3205 } else { 3206 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3207 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3208 } 3209 %} 3210 3211 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3212 3213 if (VM_Version::has_isel()) { 3214 // use isel instruction with Power 7 3215 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3216 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3217 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3218 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3219 3220 n_compare->add_req(n_region, n_src); 3221 n_compare->_opnds[0] = op_crx; 3222 n_compare->_opnds[1] = op_src; 3223 n_compare->_opnds[2] = new immL16Oper(0); 3224 3225 n_sub_base->add_req(n_region, n_src); 3226 n_sub_base->_opnds[0] = op_dst; 3227 n_sub_base->_opnds[1] = op_src; 3228 n_sub_base->_bottom_type = _bottom_type; 3229 3230 n_shift->add_req(n_region, n_sub_base); 3231 n_shift->_opnds[0] = op_dst; 3232 n_shift->_opnds[1] = op_dst; 3233 n_shift->_bottom_type = _bottom_type; 3234 3235 n_cond_set->add_req(n_region, n_compare, n_shift); 3236 n_cond_set->_opnds[0] = op_dst; 3237 n_cond_set->_opnds[1] = op_crx; 3238 n_cond_set->_opnds[2] = op_dst; 3239 n_cond_set->_bottom_type = _bottom_type; 3240 3241 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3242 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3243 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3244 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3245 3246 nodes->push(n_compare); 3247 nodes->push(n_sub_base); 3248 nodes->push(n_shift); 3249 nodes->push(n_cond_set); 3250 3251 } else { 3252 // before Power 7 3253 moveRegNode *n_move = new moveRegNode(); 3254 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3255 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3256 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3257 3258 n_move->add_req(n_region, n_src); 3259 n_move->_opnds[0] = op_dst; 3260 n_move->_opnds[1] = op_src; 3261 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3262 3263 n_compare->add_req(n_region, n_src); 3264 n_compare->add_prec(n_move); 3265 3266 n_compare->_opnds[0] = op_crx; 3267 n_compare->_opnds[1] = op_src; 3268 n_compare->_opnds[2] = new immL16Oper(0); 3269 3270 n_sub_base->add_req(n_region, n_compare, n_src); 3271 n_sub_base->_opnds[0] = op_dst; 3272 n_sub_base->_opnds[1] = op_crx; 3273 n_sub_base->_opnds[2] = op_src; 3274 n_sub_base->_bottom_type = _bottom_type; 3275 3276 n_shift->add_req(n_region, n_sub_base); 3277 n_shift->_opnds[0] = op_dst; 3278 n_shift->_opnds[1] = op_dst; 3279 n_shift->_bottom_type = _bottom_type; 3280 3281 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3282 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3283 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3284 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3285 3286 nodes->push(n_move); 3287 nodes->push(n_compare); 3288 nodes->push(n_sub_base); 3289 nodes->push(n_shift); 3290 } 3291 3292 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3293 %} 3294 3295 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3296 3297 encodeP_subNode *n1 = new encodeP_subNode(); 3298 n1->add_req(n_region, n_src); 3299 n1->_opnds[0] = op_dst; 3300 n1->_opnds[1] = op_src; 3301 n1->_bottom_type = _bottom_type; 3302 3303 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3304 n2->add_req(n_region, n1); 3305 n2->_opnds[0] = op_dst; 3306 n2->_opnds[1] = op_dst; 3307 n2->_bottom_type = _bottom_type; 3308 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3309 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3310 3311 nodes->push(n1); 3312 nodes->push(n2); 3313 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3314 %} 3315 3316 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3317 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3318 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3319 3320 n_compare->add_req(n_region, n_src); 3321 n_compare->_opnds[0] = op_crx; 3322 n_compare->_opnds[1] = op_src; 3323 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3324 3325 n_shift->add_req(n_region, n_src); 3326 n_shift->_opnds[0] = op_dst; 3327 n_shift->_opnds[1] = op_src; 3328 n_shift->_bottom_type = _bottom_type; 3329 3330 if (VM_Version::has_isel()) { 3331 // use isel instruction with Power 7 3332 3333 decodeN_addNode *n_add_base = new decodeN_addNode(); 3334 n_add_base->add_req(n_region, n_shift); 3335 n_add_base->_opnds[0] = op_dst; 3336 n_add_base->_opnds[1] = op_dst; 3337 n_add_base->_bottom_type = _bottom_type; 3338 3339 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3340 n_cond_set->add_req(n_region, n_compare, n_add_base); 3341 n_cond_set->_opnds[0] = op_dst; 3342 n_cond_set->_opnds[1] = op_crx; 3343 n_cond_set->_opnds[2] = op_dst; 3344 n_cond_set->_bottom_type = _bottom_type; 3345 3346 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3347 ra_->set_oop(n_cond_set, true); 3348 3349 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3350 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3351 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3352 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3353 3354 nodes->push(n_compare); 3355 nodes->push(n_shift); 3356 nodes->push(n_add_base); 3357 nodes->push(n_cond_set); 3358 3359 } else { 3360 // before Power 7 3361 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3362 3363 n_add_base->add_req(n_region, n_compare, n_shift); 3364 n_add_base->_opnds[0] = op_dst; 3365 n_add_base->_opnds[1] = op_crx; 3366 n_add_base->_opnds[2] = op_dst; 3367 n_add_base->_bottom_type = _bottom_type; 3368 3369 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3370 ra_->set_oop(n_add_base, true); 3371 3372 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3373 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3374 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3375 3376 nodes->push(n_compare); 3377 nodes->push(n_shift); 3378 nodes->push(n_add_base); 3379 } 3380 %} 3381 3382 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3383 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3384 n1->add_req(n_region, n_src); 3385 n1->_opnds[0] = op_dst; 3386 n1->_opnds[1] = op_src; 3387 n1->_bottom_type = _bottom_type; 3388 3389 decodeN_addNode *n2 = new decodeN_addNode(); 3390 n2->add_req(n_region, n1); 3391 n2->_opnds[0] = op_dst; 3392 n2->_opnds[1] = op_dst; 3393 n2->_bottom_type = _bottom_type; 3394 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3395 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3396 3397 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3398 ra_->set_oop(n2, true); 3399 3400 nodes->push(n1); 3401 nodes->push(n2); 3402 %} 3403 3404 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3405 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3406 3407 MacroAssembler _masm(&cbuf); 3408 int cc = $cmp$$cmpcode; 3409 int flags_reg = $crx$$reg; 3410 Label done; 3411 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3412 // Branch if not (cmp crx). 3413 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3414 __ mr($dst$$Register, $src$$Register); 3415 // TODO PPC port __ endgroup_if_needed(_size == 12); 3416 __ bind(done); 3417 %} 3418 3419 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3420 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3421 3422 MacroAssembler _masm(&cbuf); 3423 Label done; 3424 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3425 // Branch if not (cmp crx). 3426 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3427 __ li($dst$$Register, $src$$constant); 3428 // TODO PPC port __ endgroup_if_needed(_size == 12); 3429 __ bind(done); 3430 %} 3431 3432 // This enc_class is needed so that scheduler gets proper 3433 // input mapping for latency computation. 3434 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3435 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3436 MacroAssembler _masm(&cbuf); 3437 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3438 %} 3439 3440 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3441 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3442 3443 MacroAssembler _masm(&cbuf); 3444 3445 Label done; 3446 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3447 __ li($dst$$Register, $zero$$constant); 3448 __ beq($crx$$CondRegister, done); 3449 __ li($dst$$Register, $notzero$$constant); 3450 __ bind(done); 3451 %} 3452 3453 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3454 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3455 3456 MacroAssembler _masm(&cbuf); 3457 3458 Label done; 3459 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3460 __ li($dst$$Register, $zero$$constant); 3461 __ beq($crx$$CondRegister, done); 3462 __ li($dst$$Register, $notzero$$constant); 3463 __ bind(done); 3464 %} 3465 3466 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3467 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3468 3469 MacroAssembler _masm(&cbuf); 3470 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3471 Label done; 3472 __ bso($crx$$CondRegister, done); 3473 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3474 // TODO PPC port __ endgroup_if_needed(_size == 12); 3475 __ bind(done); 3476 %} 3477 3478 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3479 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3480 3481 MacroAssembler _masm(&cbuf); 3482 Label done; 3483 __ bso($crx$$CondRegister, done); 3484 __ mffprd($dst$$Register, $src$$FloatRegister); 3485 // TODO PPC port __ endgroup_if_needed(_size == 12); 3486 __ bind(done); 3487 %} 3488 3489 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3490 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3491 3492 MacroAssembler _masm(&cbuf); 3493 Label d; // dummy 3494 __ bind(d); 3495 Label* p = ($lbl$$label); 3496 // `p' is `NULL' when this encoding class is used only to 3497 // determine the size of the encoded instruction. 3498 Label& l = (NULL == p)? d : *(p); 3499 int cc = $cmp$$cmpcode; 3500 int flags_reg = $crx$$reg; 3501 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 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 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3513 cc_to_biint(cc, flags_reg), 3514 l); 3515 %} 3516 3517 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3518 // The scheduler doesn't know about branch shortening, so we set the opcode 3519 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3520 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3521 3522 MacroAssembler _masm(&cbuf); 3523 Label d; // dummy 3524 __ bind(d); 3525 Label* p = ($lbl$$label); 3526 // `p' is `NULL' when this encoding class is used only to 3527 // determine the size of the encoded instruction. 3528 Label& l = (NULL == p)? d : *(p); 3529 int cc = $cmp$$cmpcode; 3530 int flags_reg = $crx$$reg; 3531 int bhint = Assembler::bhintNoHint; 3532 3533 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3534 if (_prob <= PROB_NEVER) { 3535 bhint = Assembler::bhintIsNotTaken; 3536 } else if (_prob >= PROB_ALWAYS) { 3537 bhint = Assembler::bhintIsTaken; 3538 } 3539 } 3540 3541 // Tell the conditional far branch to optimize itself when being relocated. 3542 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3543 cc_to_biint(cc, flags_reg), 3544 l, 3545 MacroAssembler::bc_far_optimize_on_relocate); 3546 %} 3547 3548 // Branch used with Power6 scheduling (can be shortened without changing the node). 3549 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3550 // The scheduler doesn't know about branch shortening, so we set the opcode 3551 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3552 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3553 3554 MacroAssembler _masm(&cbuf); 3555 Label d; // dummy 3556 __ bind(d); 3557 Label* p = ($lbl$$label); 3558 // `p' is `NULL' when this encoding class is used only to 3559 // determine the size of the encoded instruction. 3560 Label& l = (NULL == p)? d : *(p); 3561 int cc = $cmp$$cmpcode; 3562 int flags_reg = $crx$$reg; 3563 int bhint = Assembler::bhintNoHint; 3564 3565 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3566 if (_prob <= PROB_NEVER) { 3567 bhint = Assembler::bhintIsNotTaken; 3568 } else if (_prob >= PROB_ALWAYS) { 3569 bhint = Assembler::bhintIsTaken; 3570 } 3571 } 3572 3573 #if 0 // TODO: PPC port 3574 if (_size == 8) { 3575 // Tell the conditional far branch to optimize itself when being relocated. 3576 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3577 cc_to_biint(cc, flags_reg), 3578 l, 3579 MacroAssembler::bc_far_optimize_on_relocate); 3580 } else { 3581 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3582 cc_to_biint(cc, flags_reg), 3583 l); 3584 } 3585 #endif 3586 Unimplemented(); 3587 %} 3588 3589 // Postalloc expand emitter for loading a replicatef float constant from 3590 // the method's TOC. 3591 // Enc_class needed as consttanttablebase is not supported by postalloc 3592 // expand. 3593 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3594 // Create new nodes. 3595 3596 // Make an operand with the bit pattern to load as float. 3597 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3598 3599 loadConLNodesTuple loadConLNodes = 3600 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3601 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3602 3603 // Push new nodes. 3604 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3605 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3606 3607 assert(nodes->length() >= 1, "must have created at least 1 node"); 3608 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3609 %} 3610 3611 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3612 // Create new nodes. 3613 3614 // Make an operand with the bit pattern to load as float. 3615 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3616 immI_0Oper *op_zero = new immI_0Oper(0); 3617 3618 loadConLReplicatedNodesTuple loadConLNodes = 3619 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3620 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3621 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3622 3623 // Push new nodes. 3624 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3625 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3626 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3627 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3628 3629 assert(nodes->length() >= 1, "must have created at least 1 node"); 3630 %} 3631 3632 // This enc_class is needed so that scheduler gets proper 3633 // input mapping for latency computation. 3634 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3635 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3636 // Fake operand dst needed for PPC scheduler. 3637 assert($dst$$constant == 0x0, "dst must be 0x0"); 3638 3639 MacroAssembler _masm(&cbuf); 3640 // Mark the code position where the load from the safepoint 3641 // polling page was emitted as relocInfo::poll_type. 3642 __ relocate(relocInfo::poll_type); 3643 __ load_from_polling_page($poll$$Register); 3644 %} 3645 3646 // A Java static call or a runtime call. 3647 // 3648 // Branch-and-link relative to a trampoline. 3649 // The trampoline loads the target address and does a long branch to there. 3650 // In case we call java, the trampoline branches to a interpreter_stub 3651 // which loads the inline cache and the real call target from the constant pool. 3652 // 3653 // This basically looks like this: 3654 // 3655 // >>>> consts -+ -+ 3656 // | |- offset1 3657 // [call target1] | <-+ 3658 // [IC cache] |- offset2 3659 // [call target2] <--+ 3660 // 3661 // <<<< consts 3662 // >>>> insts 3663 // 3664 // bl offset16 -+ -+ ??? // How many bits available? 3665 // | | 3666 // <<<< insts | | 3667 // >>>> stubs | | 3668 // | |- trampoline_stub_Reloc 3669 // trampoline stub: | <-+ 3670 // r2 = toc | 3671 // r2 = [r2 + offset1] | // Load call target1 from const section 3672 // mtctr r2 | 3673 // bctr |- static_stub_Reloc 3674 // comp_to_interp_stub: <---+ 3675 // r1 = toc 3676 // ICreg = [r1 + IC_offset] // Load IC from const section 3677 // r1 = [r1 + offset2] // Load call target2 from const section 3678 // mtctr r1 3679 // bctr 3680 // 3681 // <<<< stubs 3682 // 3683 // The call instruction in the code either 3684 // - Branches directly to a compiled method if the offset is encodable in instruction. 3685 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3686 // - Branches to the compiled_to_interp stub if the target is interpreted. 3687 // 3688 // Further there are three relocations from the loads to the constants in 3689 // the constant section. 3690 // 3691 // Usage of r1 and r2 in the stubs allows to distinguish them. 3692 enc_class enc_java_static_call(method meth) %{ 3693 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3694 3695 MacroAssembler _masm(&cbuf); 3696 address entry_point = (address)$meth$$method; 3697 3698 if (!_method) { 3699 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3700 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3701 } else { 3702 // Remember the offset not the address. 3703 const int start_offset = __ offset(); 3704 3705 // The trampoline stub. 3706 // No entry point given, use the current pc. 3707 // Make sure branch fits into 3708 if (entry_point == 0) entry_point = __ pc(); 3709 3710 // Put the entry point as a constant into the constant pool. 3711 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3712 if (entry_point_toc_addr == NULL) { 3713 ciEnv::current()->record_out_of_memory_failure(); 3714 return; 3715 } 3716 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3717 3718 // Emit the trampoline stub which will be related to the branch-and-link below. 3719 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3720 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3721 int method_index = resolved_method_index(cbuf); 3722 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3723 : static_call_Relocation::spec(method_index)); 3724 3725 // The real call. 3726 // Note: At this point we do not have the address of the trampoline 3727 // stub, and the entry point might be too far away for bl, so __ pc() 3728 // serves as dummy and the bl will be patched later. 3729 cbuf.set_insts_mark(); 3730 __ bl(__ pc()); // Emits a relocation. 3731 3732 // The stub for call to interpreter. 3733 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3734 if (stub == NULL) { 3735 ciEnv::current()->record_failure("CodeCache is full"); 3736 return; 3737 } 3738 } 3739 %} 3740 3741 // Second node of expanded dynamic call - the call. 3742 enc_class enc_java_dynamic_call_sched(method meth) %{ 3743 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3744 3745 MacroAssembler _masm(&cbuf); 3746 3747 if (!ra_->C->in_scratch_emit_size()) { 3748 // Create a call trampoline stub for the given method. 3749 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3750 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3751 if (entry_point_const == NULL) { 3752 ciEnv::current()->record_out_of_memory_failure(); 3753 return; 3754 } 3755 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3756 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3757 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3758 3759 // Build relocation at call site with ic position as data. 3760 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3761 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3762 "must have one, but can't have both"); 3763 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3764 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3765 "must contain instruction offset"); 3766 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3767 ? _load_ic_hi_node->_cbuf_insts_offset 3768 : _load_ic_node->_cbuf_insts_offset; 3769 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3770 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3771 "should be load from TOC"); 3772 int method_index = resolved_method_index(cbuf); 3773 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3774 } 3775 3776 // At this point I do not have the address of the trampoline stub, 3777 // and the entry point might be too far away for bl. Pc() serves 3778 // as dummy and bl will be patched later. 3779 __ bl((address) __ pc()); 3780 %} 3781 3782 // postalloc expand emitter for virtual calls. 3783 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3784 3785 // Create the nodes for loading the IC from the TOC. 3786 loadConLNodesTuple loadConLNodes_IC = 3787 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3788 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3789 3790 // Create the call node. 3791 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3792 call->_method_handle_invoke = _method_handle_invoke; 3793 call->_vtable_index = _vtable_index; 3794 call->_method = _method; 3795 call->_bci = _bci; 3796 call->_optimized_virtual = _optimized_virtual; 3797 call->_tf = _tf; 3798 call->_entry_point = _entry_point; 3799 call->_cnt = _cnt; 3800 call->_argsize = _argsize; 3801 call->_oop_map = _oop_map; 3802 call->_jvms = _jvms; 3803 call->_jvmadj = _jvmadj; 3804 call->_in_rms = _in_rms; 3805 call->_nesting = _nesting; 3806 call->_override_symbolic_info = _override_symbolic_info; 3807 3808 // New call needs all inputs of old call. 3809 // Req... 3810 for (uint i = 0; i < req(); ++i) { 3811 // The expanded node does not need toc any more. 3812 // Add the inline cache constant here instead. This expresses the 3813 // register of the inline cache must be live at the call. 3814 // Else we would have to adapt JVMState by -1. 3815 if (i == mach_constant_base_node_input()) { 3816 call->add_req(loadConLNodes_IC._last); 3817 } else { 3818 call->add_req(in(i)); 3819 } 3820 } 3821 // ...as well as prec 3822 for (uint i = req(); i < len(); ++i) { 3823 call->add_prec(in(i)); 3824 } 3825 3826 // Remember nodes loading the inline cache into r19. 3827 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3828 call->_load_ic_node = loadConLNodes_IC._small; 3829 3830 // Operands for new nodes. 3831 call->_opnds[0] = _opnds[0]; 3832 call->_opnds[1] = _opnds[1]; 3833 3834 // Only the inline cache is associated with a register. 3835 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3836 3837 // Push new nodes. 3838 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3839 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3840 nodes->push(call); 3841 %} 3842 3843 // Compound version of call dynamic 3844 // Toc is only passed so that it can be used in ins_encode statement. 3845 // In the code we have to use $constanttablebase. 3846 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3847 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3848 MacroAssembler _masm(&cbuf); 3849 int start_offset = __ offset(); 3850 3851 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3852 #if 0 3853 int vtable_index = this->_vtable_index; 3854 if (_vtable_index < 0) { 3855 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3856 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3857 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3858 3859 // Virtual call relocation will point to ic load. 3860 address virtual_call_meta_addr = __ pc(); 3861 // Load a clear inline cache. 3862 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3863 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3864 if (!success) { 3865 ciEnv::current()->record_out_of_memory_failure(); 3866 return; 3867 } 3868 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3869 // to determine who we intended to call. 3870 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3871 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3872 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3873 "Fix constant in ret_addr_offset()"); 3874 } else { 3875 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3876 // Go thru the vtable. Get receiver klass. Receiver already 3877 // checked for non-null. If we'll go thru a C2I adapter, the 3878 // interpreter expects method in R19_method. 3879 3880 __ load_klass(R11_scratch1, R3); 3881 3882 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3883 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3884 __ li(R19_method, v_off); 3885 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3886 // NOTE: for vtable dispatches, the vtable entry will never be 3887 // null. However it may very well end up in handle_wrong_method 3888 // if the method is abstract for the particular class. 3889 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3890 // Call target. Either compiled code or C2I adapter. 3891 __ mtctr(R11_scratch1); 3892 __ bctrl(); 3893 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3894 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3895 } 3896 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3897 "Fix constant in ret_addr_offset()"); 3898 } 3899 #endif 3900 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3901 %} 3902 3903 // a runtime call 3904 enc_class enc_java_to_runtime_call (method meth) %{ 3905 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3906 3907 MacroAssembler _masm(&cbuf); 3908 const address start_pc = __ pc(); 3909 3910 #if defined(ABI_ELFv2) 3911 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3912 __ call_c(entry, relocInfo::runtime_call_type); 3913 #else 3914 // The function we're going to call. 3915 FunctionDescriptor fdtemp; 3916 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3917 3918 Register Rtoc = R12_scratch2; 3919 // Calculate the method's TOC. 3920 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3921 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3922 // pool entries; call_c_using_toc will optimize the call. 3923 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3924 if (!success) { 3925 ciEnv::current()->record_out_of_memory_failure(); 3926 return; 3927 } 3928 #endif 3929 3930 // Check the ret_addr_offset. 3931 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3932 "Fix constant in ret_addr_offset()"); 3933 %} 3934 3935 // Move to ctr for leaf call. 3936 // This enc_class is needed so that scheduler gets proper 3937 // input mapping for latency computation. 3938 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3939 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3940 MacroAssembler _masm(&cbuf); 3941 __ mtctr($src$$Register); 3942 %} 3943 3944 // Postalloc expand emitter for runtime leaf calls. 3945 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3946 loadConLNodesTuple loadConLNodes_Entry; 3947 #if defined(ABI_ELFv2) 3948 jlong entry_address = (jlong) this->entry_point(); 3949 assert(entry_address, "need address here"); 3950 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3951 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3952 #else 3953 // Get the struct that describes the function we are about to call. 3954 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3955 assert(fd, "need fd here"); 3956 jlong entry_address = (jlong) fd->entry(); 3957 // new nodes 3958 loadConLNodesTuple loadConLNodes_Env; 3959 loadConLNodesTuple loadConLNodes_Toc; 3960 3961 // Create nodes and operands for loading the entry point. 3962 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3963 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3964 3965 3966 // Create nodes and operands for loading the env pointer. 3967 if (fd->env() != NULL) { 3968 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3969 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3970 } else { 3971 loadConLNodes_Env._large_hi = NULL; 3972 loadConLNodes_Env._large_lo = NULL; 3973 loadConLNodes_Env._small = NULL; 3974 loadConLNodes_Env._last = new loadConL16Node(); 3975 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3976 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3977 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3978 } 3979 3980 // Create nodes and operands for loading the Toc point. 3981 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3982 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3983 #endif // ABI_ELFv2 3984 // mtctr node 3985 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3986 3987 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3988 mtctr->add_req(0, loadConLNodes_Entry._last); 3989 3990 mtctr->_opnds[0] = new iRegLdstOper(); 3991 mtctr->_opnds[1] = new iRegLdstOper(); 3992 3993 // call node 3994 MachCallLeafNode *call = new CallLeafDirectNode(); 3995 3996 call->_opnds[0] = _opnds[0]; 3997 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3998 3999 // Make the new call node look like the old one. 4000 call->_name = _name; 4001 call->_tf = _tf; 4002 call->_entry_point = _entry_point; 4003 call->_cnt = _cnt; 4004 call->_argsize = _argsize; 4005 call->_oop_map = _oop_map; 4006 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 4007 call->_jvms = NULL; 4008 call->_jvmadj = _jvmadj; 4009 call->_in_rms = _in_rms; 4010 call->_nesting = _nesting; 4011 4012 4013 // New call needs all inputs of old call. 4014 // Req... 4015 for (uint i = 0; i < req(); ++i) { 4016 if (i != mach_constant_base_node_input()) { 4017 call->add_req(in(i)); 4018 } 4019 } 4020 4021 // These must be reqired edges, as the registers are live up to 4022 // the call. Else the constants are handled as kills. 4023 call->add_req(mtctr); 4024 #if !defined(ABI_ELFv2) 4025 call->add_req(loadConLNodes_Env._last); 4026 call->add_req(loadConLNodes_Toc._last); 4027 #endif 4028 4029 // ...as well as prec 4030 for (uint i = req(); i < len(); ++i) { 4031 call->add_prec(in(i)); 4032 } 4033 4034 // registers 4035 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4036 4037 // Insert the new nodes. 4038 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4039 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4040 #if !defined(ABI_ELFv2) 4041 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4042 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4043 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4044 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4045 #endif 4046 nodes->push(mtctr); 4047 nodes->push(call); 4048 %} 4049 %} 4050 4051 //----------FRAME-------------------------------------------------------------- 4052 // Definition of frame structure and management information. 4053 4054 frame %{ 4055 // What direction does stack grow in (assumed to be same for native & Java). 4056 stack_direction(TOWARDS_LOW); 4057 4058 // These two registers define part of the calling convention between 4059 // compiled code and the interpreter. 4060 4061 // Inline Cache Register or method for I2C. 4062 inline_cache_reg(R19); // R19_method 4063 4064 // Method Oop Register when calling interpreter. 4065 interpreter_method_oop_reg(R19); // R19_method 4066 4067 // Optional: name the operand used by cisc-spilling to access 4068 // [stack_pointer + offset]. 4069 cisc_spilling_operand_name(indOffset); 4070 4071 // Number of stack slots consumed by a Monitor enter. 4072 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4073 4074 // Compiled code's Frame Pointer. 4075 frame_pointer(R1); // R1_SP 4076 4077 // Interpreter stores its frame pointer in a register which is 4078 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4079 // interpreted java to compiled java. 4080 // 4081 // R14_state holds pointer to caller's cInterpreter. 4082 interpreter_frame_pointer(R14); // R14_state 4083 4084 stack_alignment(frame::alignment_in_bytes); 4085 4086 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4087 4088 // Number of outgoing stack slots killed above the 4089 // out_preserve_stack_slots for calls to C. Supports the var-args 4090 // backing area for register parms. 4091 // 4092 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4093 4094 // The after-PROLOG location of the return address. Location of 4095 // return address specifies a type (REG or STACK) and a number 4096 // representing the register number (i.e. - use a register name) or 4097 // stack slot. 4098 // 4099 // A: Link register is stored in stack slot ... 4100 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4101 // J: Therefore, we make sure that the link register is also in R11_scratch1 4102 // at the end of the prolog. 4103 // B: We use R20, now. 4104 //return_addr(REG R20); 4105 4106 // G: After reading the comments made by all the luminaries on their 4107 // failure to tell the compiler where the return address really is, 4108 // I hardly dare to try myself. However, I'm convinced it's in slot 4109 // 4 what apparently works and saves us some spills. 4110 return_addr(STACK 4); 4111 4112 // This is the body of the function 4113 // 4114 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4115 // uint length, // length of array 4116 // bool is_outgoing) 4117 // 4118 // The `sig' array is to be updated. sig[j] represents the location 4119 // of the j-th argument, either a register or a stack slot. 4120 4121 // Comment taken from i486.ad: 4122 // Body of function which returns an integer array locating 4123 // arguments either in registers or in stack slots. Passed an array 4124 // of ideal registers called "sig" and a "length" count. Stack-slot 4125 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4126 // arguments for a CALLEE. Incoming stack arguments are 4127 // automatically biased by the preserve_stack_slots field above. 4128 calling_convention %{ 4129 // No difference between ingoing/outgoing. Just pass false. 4130 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4131 %} 4132 4133 // Comment taken from i486.ad: 4134 // Body of function which returns an integer array locating 4135 // arguments either in registers or in stack slots. Passed an array 4136 // of ideal registers called "sig" and a "length" count. Stack-slot 4137 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4138 // arguments for a CALLEE. Incoming stack arguments are 4139 // automatically biased by the preserve_stack_slots field above. 4140 c_calling_convention %{ 4141 // This is obviously always outgoing. 4142 // C argument in register AND stack slot. 4143 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4144 %} 4145 4146 // Location of native (C/C++) and interpreter return values. This 4147 // is specified to be the same as Java. In the 32-bit VM, long 4148 // values are actually returned from native calls in O0:O1 and 4149 // returned to the interpreter in I0:I1. The copying to and from 4150 // the register pairs is done by the appropriate call and epilog 4151 // opcodes. This simplifies the register allocator. 4152 c_return_value %{ 4153 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4154 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4155 "only return normal values"); 4156 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4157 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4158 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4159 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4160 %} 4161 4162 // Location of compiled Java return values. Same as C 4163 return_value %{ 4164 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4165 (ideal_reg == Op_RegN && CompressedOops::base() == NULL && CompressedOops::shift() == 0), 4166 "only return normal values"); 4167 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4168 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4169 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4170 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4171 %} 4172 %} 4173 4174 4175 //----------ATTRIBUTES--------------------------------------------------------- 4176 4177 //----------Operand Attributes------------------------------------------------- 4178 op_attrib op_cost(1); // Required cost attribute. 4179 4180 //----------Instruction Attributes--------------------------------------------- 4181 4182 // Cost attribute. required. 4183 ins_attrib ins_cost(DEFAULT_COST); 4184 4185 // Is this instruction a non-matching short branch variant of some 4186 // long branch? Not required. 4187 ins_attrib ins_short_branch(0); 4188 4189 ins_attrib ins_is_TrapBasedCheckNode(true); 4190 4191 // Number of constants. 4192 // This instruction uses the given number of constants 4193 // (optional attribute). 4194 // This is needed to determine in time whether the constant pool will 4195 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4196 // is determined. It's also used to compute the constant pool size 4197 // in Output(). 4198 ins_attrib ins_num_consts(0); 4199 4200 // Required alignment attribute (must be a power of 2) specifies the 4201 // alignment that some part of the instruction (not necessarily the 4202 // start) requires. If > 1, a compute_padding() function must be 4203 // provided for the instruction. 4204 ins_attrib ins_alignment(1); 4205 4206 // Enforce/prohibit rematerializations. 4207 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4208 // then rematerialization of that instruction is prohibited and the 4209 // instruction's value will be spilled if necessary. 4210 // Causes that MachNode::rematerialize() returns false. 4211 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4212 // then rematerialization should be enforced and a copy of the instruction 4213 // should be inserted if possible; rematerialization is not guaranteed. 4214 // Note: this may result in rematerializations in front of every use. 4215 // Causes that MachNode::rematerialize() can return true. 4216 // (optional attribute) 4217 ins_attrib ins_cannot_rematerialize(false); 4218 ins_attrib ins_should_rematerialize(false); 4219 4220 // Instruction has variable size depending on alignment. 4221 ins_attrib ins_variable_size_depending_on_alignment(false); 4222 4223 // Instruction is a nop. 4224 ins_attrib ins_is_nop(false); 4225 4226 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4227 ins_attrib ins_use_mach_if_fast_lock_node(false); 4228 4229 // Field for the toc offset of a constant. 4230 // 4231 // This is needed if the toc offset is not encodable as an immediate in 4232 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4233 // added to the toc, and from this a load with immediate is performed. 4234 // With postalloc expand, we get two nodes that require the same offset 4235 // but which don't know about each other. The offset is only known 4236 // when the constant is added to the constant pool during emitting. 4237 // It is generated in the 'hi'-node adding the upper bits, and saved 4238 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4239 // the offset from there when it gets encoded. 4240 ins_attrib ins_field_const_toc_offset(0); 4241 ins_attrib ins_field_const_toc_offset_hi_node(0); 4242 4243 // A field that can hold the instructions offset in the code buffer. 4244 // Set in the nodes emitter. 4245 ins_attrib ins_field_cbuf_insts_offset(-1); 4246 4247 // Fields for referencing a call's load-IC-node. 4248 // If the toc offset can not be encoded as an immediate in a load, we 4249 // use two nodes. 4250 ins_attrib ins_field_load_ic_hi_node(0); 4251 ins_attrib ins_field_load_ic_node(0); 4252 4253 //----------OPERANDS----------------------------------------------------------- 4254 // Operand definitions must precede instruction definitions for correct 4255 // parsing in the ADLC because operands constitute user defined types 4256 // which are used in instruction definitions. 4257 // 4258 // Formats are generated automatically for constants and base registers. 4259 4260 operand vecX() %{ 4261 constraint(ALLOC_IN_RC(vs_reg)); 4262 match(VecX); 4263 4264 format %{ %} 4265 interface(REG_INTER); 4266 %} 4267 4268 //----------Simple Operands---------------------------------------------------- 4269 // Immediate Operands 4270 4271 // Integer Immediate: 32-bit 4272 operand immI() %{ 4273 match(ConI); 4274 op_cost(40); 4275 format %{ %} 4276 interface(CONST_INTER); 4277 %} 4278 4279 operand immI8() %{ 4280 predicate(Assembler::is_simm(n->get_int(), 8)); 4281 op_cost(0); 4282 match(ConI); 4283 format %{ %} 4284 interface(CONST_INTER); 4285 %} 4286 4287 // Integer Immediate: 16-bit 4288 operand immI16() %{ 4289 predicate(Assembler::is_simm(n->get_int(), 16)); 4290 op_cost(0); 4291 match(ConI); 4292 format %{ %} 4293 interface(CONST_INTER); 4294 %} 4295 4296 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4297 operand immIhi16() %{ 4298 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4299 match(ConI); 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 operand immInegpow2() %{ 4306 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4307 match(ConI); 4308 op_cost(0); 4309 format %{ %} 4310 interface(CONST_INTER); 4311 %} 4312 4313 operand immIpow2minus1() %{ 4314 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4315 match(ConI); 4316 op_cost(0); 4317 format %{ %} 4318 interface(CONST_INTER); 4319 %} 4320 4321 operand immIpowerOf2() %{ 4322 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4323 match(ConI); 4324 op_cost(0); 4325 format %{ %} 4326 interface(CONST_INTER); 4327 %} 4328 4329 // Unsigned Integer Immediate: the values 0-31 4330 operand uimmI5() %{ 4331 predicate(Assembler::is_uimm(n->get_int(), 5)); 4332 match(ConI); 4333 op_cost(0); 4334 format %{ %} 4335 interface(CONST_INTER); 4336 %} 4337 4338 // Unsigned Integer Immediate: 6-bit 4339 operand uimmI6() %{ 4340 predicate(Assembler::is_uimm(n->get_int(), 6)); 4341 match(ConI); 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Unsigned Integer Immediate: 6-bit int, greater than 32 4348 operand uimmI6_ge32() %{ 4349 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4350 match(ConI); 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Unsigned Integer Immediate: 15-bit 4357 operand uimmI15() %{ 4358 predicate(Assembler::is_uimm(n->get_int(), 15)); 4359 match(ConI); 4360 op_cost(0); 4361 format %{ %} 4362 interface(CONST_INTER); 4363 %} 4364 4365 // Unsigned Integer Immediate: 16-bit 4366 operand uimmI16() %{ 4367 predicate(Assembler::is_uimm(n->get_int(), 16)); 4368 match(ConI); 4369 op_cost(0); 4370 format %{ %} 4371 interface(CONST_INTER); 4372 %} 4373 4374 // constant 'int 0'. 4375 operand immI_0() %{ 4376 predicate(n->get_int() == 0); 4377 match(ConI); 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // constant 'int 1'. 4384 operand immI_1() %{ 4385 predicate(n->get_int() == 1); 4386 match(ConI); 4387 op_cost(0); 4388 format %{ %} 4389 interface(CONST_INTER); 4390 %} 4391 4392 // constant 'int -1'. 4393 operand immI_minus1() %{ 4394 predicate(n->get_int() == -1); 4395 match(ConI); 4396 op_cost(0); 4397 format %{ %} 4398 interface(CONST_INTER); 4399 %} 4400 4401 // int value 16. 4402 operand immI_16() %{ 4403 predicate(n->get_int() == 16); 4404 match(ConI); 4405 op_cost(0); 4406 format %{ %} 4407 interface(CONST_INTER); 4408 %} 4409 4410 // int value 24. 4411 operand immI_24() %{ 4412 predicate(n->get_int() == 24); 4413 match(ConI); 4414 op_cost(0); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 // Compressed oops constants 4420 // Pointer Immediate 4421 operand immN() %{ 4422 match(ConN); 4423 4424 op_cost(10); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // NULL Pointer Immediate 4430 operand immN_0() %{ 4431 predicate(n->get_narrowcon() == 0); 4432 match(ConN); 4433 4434 op_cost(0); 4435 format %{ %} 4436 interface(CONST_INTER); 4437 %} 4438 4439 // Compressed klass constants 4440 operand immNKlass() %{ 4441 match(ConNKlass); 4442 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 // This operand can be used to avoid matching of an instruct 4449 // with chain rule. 4450 operand immNKlass_NM() %{ 4451 match(ConNKlass); 4452 predicate(false); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 // Pointer Immediate: 64-bit 4459 operand immP() %{ 4460 match(ConP); 4461 op_cost(0); 4462 format %{ %} 4463 interface(CONST_INTER); 4464 %} 4465 4466 // Operand to avoid match of loadConP. 4467 // This operand can be used to avoid matching of an instruct 4468 // with chain rule. 4469 operand immP_NM() %{ 4470 match(ConP); 4471 predicate(false); 4472 op_cost(0); 4473 format %{ %} 4474 interface(CONST_INTER); 4475 %} 4476 4477 // costant 'pointer 0'. 4478 operand immP_0() %{ 4479 predicate(n->get_ptr() == 0); 4480 match(ConP); 4481 op_cost(0); 4482 format %{ %} 4483 interface(CONST_INTER); 4484 %} 4485 4486 // pointer 0x0 or 0x1 4487 operand immP_0or1() %{ 4488 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4489 match(ConP); 4490 op_cost(0); 4491 format %{ %} 4492 interface(CONST_INTER); 4493 %} 4494 4495 operand immL() %{ 4496 match(ConL); 4497 op_cost(40); 4498 format %{ %} 4499 interface(CONST_INTER); 4500 %} 4501 4502 operand immLmax30() %{ 4503 predicate((n->get_long() <= 30)); 4504 match(ConL); 4505 op_cost(0); 4506 format %{ %} 4507 interface(CONST_INTER); 4508 %} 4509 4510 // Long Immediate: 16-bit 4511 operand immL16() %{ 4512 predicate(Assembler::is_simm(n->get_long(), 16)); 4513 match(ConL); 4514 op_cost(0); 4515 format %{ %} 4516 interface(CONST_INTER); 4517 %} 4518 4519 // Long Immediate: 16-bit, 4-aligned 4520 operand immL16Alg4() %{ 4521 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4522 match(ConL); 4523 op_cost(0); 4524 format %{ %} 4525 interface(CONST_INTER); 4526 %} 4527 4528 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4529 operand immL32hi16() %{ 4530 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4531 match(ConL); 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 // Long Immediate: 32-bit 4538 operand immL32() %{ 4539 predicate(Assembler::is_simm(n->get_long(), 32)); 4540 match(ConL); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4547 operand immLhighest16() %{ 4548 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4549 match(ConL); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 operand immLnegpow2() %{ 4556 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4557 match(ConL); 4558 op_cost(0); 4559 format %{ %} 4560 interface(CONST_INTER); 4561 %} 4562 4563 operand immLpow2minus1() %{ 4564 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4565 (n->get_long() != (jlong)0xffffffffffffffffL)); 4566 match(ConL); 4567 op_cost(0); 4568 format %{ %} 4569 interface(CONST_INTER); 4570 %} 4571 4572 // constant 'long 0'. 4573 operand immL_0() %{ 4574 predicate(n->get_long() == 0L); 4575 match(ConL); 4576 op_cost(0); 4577 format %{ %} 4578 interface(CONST_INTER); 4579 %} 4580 4581 // constat ' long -1'. 4582 operand immL_minus1() %{ 4583 predicate(n->get_long() == -1L); 4584 match(ConL); 4585 op_cost(0); 4586 format %{ %} 4587 interface(CONST_INTER); 4588 %} 4589 4590 // Long Immediate: low 32-bit mask 4591 operand immL_32bits() %{ 4592 predicate(n->get_long() == 0xFFFFFFFFL); 4593 match(ConL); 4594 op_cost(0); 4595 format %{ %} 4596 interface(CONST_INTER); 4597 %} 4598 4599 // Unsigned Long Immediate: 16-bit 4600 operand uimmL16() %{ 4601 predicate(Assembler::is_uimm(n->get_long(), 16)); 4602 match(ConL); 4603 op_cost(0); 4604 format %{ %} 4605 interface(CONST_INTER); 4606 %} 4607 4608 // Float Immediate 4609 operand immF() %{ 4610 match(ConF); 4611 op_cost(40); 4612 format %{ %} 4613 interface(CONST_INTER); 4614 %} 4615 4616 // Float Immediate: +0.0f. 4617 operand immF_0() %{ 4618 predicate(jint_cast(n->getf()) == 0); 4619 match(ConF); 4620 4621 op_cost(0); 4622 format %{ %} 4623 interface(CONST_INTER); 4624 %} 4625 4626 // Double Immediate 4627 operand immD() %{ 4628 match(ConD); 4629 op_cost(40); 4630 format %{ %} 4631 interface(CONST_INTER); 4632 %} 4633 4634 // Integer Register Operands 4635 // Integer Destination Register 4636 // See definition of reg_class bits32_reg_rw. 4637 operand iRegIdst() %{ 4638 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4639 match(RegI); 4640 match(rscratch1RegI); 4641 match(rscratch2RegI); 4642 match(rarg1RegI); 4643 match(rarg2RegI); 4644 match(rarg3RegI); 4645 match(rarg4RegI); 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 // Integer Source Register 4651 // See definition of reg_class bits32_reg_ro. 4652 operand iRegIsrc() %{ 4653 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4654 match(RegI); 4655 match(rscratch1RegI); 4656 match(rscratch2RegI); 4657 match(rarg1RegI); 4658 match(rarg2RegI); 4659 match(rarg3RegI); 4660 match(rarg4RegI); 4661 format %{ %} 4662 interface(REG_INTER); 4663 %} 4664 4665 operand rscratch1RegI() %{ 4666 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4667 match(iRegIdst); 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 operand rscratch2RegI() %{ 4673 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4674 match(iRegIdst); 4675 format %{ %} 4676 interface(REG_INTER); 4677 %} 4678 4679 operand rarg1RegI() %{ 4680 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4681 match(iRegIdst); 4682 format %{ %} 4683 interface(REG_INTER); 4684 %} 4685 4686 operand rarg2RegI() %{ 4687 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4688 match(iRegIdst); 4689 format %{ %} 4690 interface(REG_INTER); 4691 %} 4692 4693 operand rarg3RegI() %{ 4694 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4695 match(iRegIdst); 4696 format %{ %} 4697 interface(REG_INTER); 4698 %} 4699 4700 operand rarg4RegI() %{ 4701 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4702 match(iRegIdst); 4703 format %{ %} 4704 interface(REG_INTER); 4705 %} 4706 4707 operand rarg1RegL() %{ 4708 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4709 match(iRegLdst); 4710 format %{ %} 4711 interface(REG_INTER); 4712 %} 4713 4714 operand rarg2RegL() %{ 4715 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4716 match(iRegLdst); 4717 format %{ %} 4718 interface(REG_INTER); 4719 %} 4720 4721 operand rarg3RegL() %{ 4722 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4723 match(iRegLdst); 4724 format %{ %} 4725 interface(REG_INTER); 4726 %} 4727 4728 operand rarg4RegL() %{ 4729 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4730 match(iRegLdst); 4731 format %{ %} 4732 interface(REG_INTER); 4733 %} 4734 4735 // Pointer Destination Register 4736 // See definition of reg_class bits64_reg_rw. 4737 operand iRegPdst() %{ 4738 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4739 match(RegP); 4740 match(rscratch1RegP); 4741 match(rscratch2RegP); 4742 match(rarg1RegP); 4743 match(rarg2RegP); 4744 match(rarg3RegP); 4745 match(rarg4RegP); 4746 format %{ %} 4747 interface(REG_INTER); 4748 %} 4749 4750 // Pointer Destination Register 4751 // Operand not using r11 and r12 (killed in epilog). 4752 operand iRegPdstNoScratch() %{ 4753 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4754 match(RegP); 4755 match(rarg1RegP); 4756 match(rarg2RegP); 4757 match(rarg3RegP); 4758 match(rarg4RegP); 4759 format %{ %} 4760 interface(REG_INTER); 4761 %} 4762 4763 // Pointer Source Register 4764 // See definition of reg_class bits64_reg_ro. 4765 operand iRegPsrc() %{ 4766 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4767 match(RegP); 4768 match(iRegPdst); 4769 match(rscratch1RegP); 4770 match(rscratch2RegP); 4771 match(rarg1RegP); 4772 match(rarg2RegP); 4773 match(rarg3RegP); 4774 match(rarg4RegP); 4775 match(threadRegP); 4776 format %{ %} 4777 interface(REG_INTER); 4778 %} 4779 4780 // Thread operand. 4781 operand threadRegP() %{ 4782 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4783 match(iRegPdst); 4784 format %{ "R16" %} 4785 interface(REG_INTER); 4786 %} 4787 4788 operand rscratch1RegP() %{ 4789 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4790 match(iRegPdst); 4791 format %{ "R11" %} 4792 interface(REG_INTER); 4793 %} 4794 4795 operand rscratch2RegP() %{ 4796 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4797 match(iRegPdst); 4798 format %{ %} 4799 interface(REG_INTER); 4800 %} 4801 4802 operand rarg1RegP() %{ 4803 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4804 match(iRegPdst); 4805 format %{ %} 4806 interface(REG_INTER); 4807 %} 4808 4809 operand rarg2RegP() %{ 4810 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4811 match(iRegPdst); 4812 format %{ %} 4813 interface(REG_INTER); 4814 %} 4815 4816 operand rarg3RegP() %{ 4817 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4818 match(iRegPdst); 4819 format %{ %} 4820 interface(REG_INTER); 4821 %} 4822 4823 operand rarg4RegP() %{ 4824 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4825 match(iRegPdst); 4826 format %{ %} 4827 interface(REG_INTER); 4828 %} 4829 4830 operand iRegNsrc() %{ 4831 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4832 match(RegN); 4833 match(iRegNdst); 4834 4835 format %{ %} 4836 interface(REG_INTER); 4837 %} 4838 4839 operand iRegNdst() %{ 4840 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4841 match(RegN); 4842 4843 format %{ %} 4844 interface(REG_INTER); 4845 %} 4846 4847 // Long Destination Register 4848 // See definition of reg_class bits64_reg_rw. 4849 operand iRegLdst() %{ 4850 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4851 match(RegL); 4852 match(rscratch1RegL); 4853 match(rscratch2RegL); 4854 format %{ %} 4855 interface(REG_INTER); 4856 %} 4857 4858 // Long Source Register 4859 // See definition of reg_class bits64_reg_ro. 4860 operand iRegLsrc() %{ 4861 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4862 match(RegL); 4863 match(iRegLdst); 4864 match(rscratch1RegL); 4865 match(rscratch2RegL); 4866 format %{ %} 4867 interface(REG_INTER); 4868 %} 4869 4870 // Special operand for ConvL2I. 4871 operand iRegL2Isrc(iRegLsrc reg) %{ 4872 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4873 match(ConvL2I reg); 4874 format %{ "ConvL2I($reg)" %} 4875 interface(REG_INTER) 4876 %} 4877 4878 operand rscratch1RegL() %{ 4879 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4880 match(RegL); 4881 format %{ %} 4882 interface(REG_INTER); 4883 %} 4884 4885 operand rscratch2RegL() %{ 4886 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4887 match(RegL); 4888 format %{ %} 4889 interface(REG_INTER); 4890 %} 4891 4892 // Condition Code Flag Registers 4893 operand flagsReg() %{ 4894 constraint(ALLOC_IN_RC(int_flags)); 4895 match(RegFlags); 4896 format %{ %} 4897 interface(REG_INTER); 4898 %} 4899 4900 operand flagsRegSrc() %{ 4901 constraint(ALLOC_IN_RC(int_flags_ro)); 4902 match(RegFlags); 4903 match(flagsReg); 4904 match(flagsRegCR0); 4905 format %{ %} 4906 interface(REG_INTER); 4907 %} 4908 4909 // Condition Code Flag Register CR0 4910 operand flagsRegCR0() %{ 4911 constraint(ALLOC_IN_RC(int_flags_CR0)); 4912 match(RegFlags); 4913 format %{ "CR0" %} 4914 interface(REG_INTER); 4915 %} 4916 4917 operand flagsRegCR1() %{ 4918 constraint(ALLOC_IN_RC(int_flags_CR1)); 4919 match(RegFlags); 4920 format %{ "CR1" %} 4921 interface(REG_INTER); 4922 %} 4923 4924 operand flagsRegCR6() %{ 4925 constraint(ALLOC_IN_RC(int_flags_CR6)); 4926 match(RegFlags); 4927 format %{ "CR6" %} 4928 interface(REG_INTER); 4929 %} 4930 4931 operand regCTR() %{ 4932 constraint(ALLOC_IN_RC(ctr_reg)); 4933 // RegFlags should work. Introducing a RegSpecial type would cause a 4934 // lot of changes. 4935 match(RegFlags); 4936 format %{"SR_CTR" %} 4937 interface(REG_INTER); 4938 %} 4939 4940 operand regD() %{ 4941 constraint(ALLOC_IN_RC(dbl_reg)); 4942 match(RegD); 4943 format %{ %} 4944 interface(REG_INTER); 4945 %} 4946 4947 operand regF() %{ 4948 constraint(ALLOC_IN_RC(flt_reg)); 4949 match(RegF); 4950 format %{ %} 4951 interface(REG_INTER); 4952 %} 4953 4954 // Special Registers 4955 4956 // Method Register 4957 operand inline_cache_regP(iRegPdst reg) %{ 4958 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4959 match(reg); 4960 format %{ %} 4961 interface(REG_INTER); 4962 %} 4963 4964 operand compiler_method_oop_regP(iRegPdst reg) %{ 4965 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4966 match(reg); 4967 format %{ %} 4968 interface(REG_INTER); 4969 %} 4970 4971 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4972 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4973 match(reg); 4974 format %{ %} 4975 interface(REG_INTER); 4976 %} 4977 4978 // Operands to remove register moves in unscaled mode. 4979 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4980 operand iRegP2N(iRegPsrc reg) %{ 4981 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& CompressedOops::shift() == 0); 4982 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4983 match(EncodeP reg); 4984 format %{ "$reg" %} 4985 interface(REG_INTER) 4986 %} 4987 4988 operand iRegN2P(iRegNsrc reg) %{ 4989 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4990 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4991 match(DecodeN reg); 4992 format %{ "$reg" %} 4993 interface(REG_INTER) 4994 %} 4995 4996 operand iRegN2P_klass(iRegNsrc reg) %{ 4997 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 4998 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4999 match(DecodeNKlass reg); 5000 format %{ "$reg" %} 5001 interface(REG_INTER) 5002 %} 5003 5004 //----------Complex Operands--------------------------------------------------- 5005 // Indirect Memory Reference 5006 operand indirect(iRegPsrc reg) %{ 5007 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5008 match(reg); 5009 op_cost(100); 5010 format %{ "[$reg]" %} 5011 interface(MEMORY_INTER) %{ 5012 base($reg); 5013 index(0x0); 5014 scale(0x0); 5015 disp(0x0); 5016 %} 5017 %} 5018 5019 // Indirect with Offset 5020 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 5021 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5022 match(AddP reg offset); 5023 op_cost(100); 5024 format %{ "[$reg + $offset]" %} 5025 interface(MEMORY_INTER) %{ 5026 base($reg); 5027 index(0x0); 5028 scale(0x0); 5029 disp($offset); 5030 %} 5031 %} 5032 5033 // Indirect with 4-aligned Offset 5034 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5035 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5036 match(AddP reg offset); 5037 op_cost(100); 5038 format %{ "[$reg + $offset]" %} 5039 interface(MEMORY_INTER) %{ 5040 base($reg); 5041 index(0x0); 5042 scale(0x0); 5043 disp($offset); 5044 %} 5045 %} 5046 5047 //----------Complex Operands for Compressed OOPs------------------------------- 5048 // Compressed OOPs with narrow_oop_shift == 0. 5049 5050 // Indirect Memory Reference, compressed OOP 5051 operand indirectNarrow(iRegNsrc reg) %{ 5052 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5053 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5054 match(DecodeN reg); 5055 op_cost(100); 5056 format %{ "[$reg]" %} 5057 interface(MEMORY_INTER) %{ 5058 base($reg); 5059 index(0x0); 5060 scale(0x0); 5061 disp(0x0); 5062 %} 5063 %} 5064 5065 operand indirectNarrow_klass(iRegNsrc reg) %{ 5066 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5067 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5068 match(DecodeNKlass reg); 5069 op_cost(100); 5070 format %{ "[$reg]" %} 5071 interface(MEMORY_INTER) %{ 5072 base($reg); 5073 index(0x0); 5074 scale(0x0); 5075 disp(0x0); 5076 %} 5077 %} 5078 5079 // Indirect with Offset, compressed OOP 5080 operand indOffset16Narrow(iRegNsrc reg, immL16 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 indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5095 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::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 // Indirect with 4-aligned Offset, compressed OOP 5109 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5110 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5111 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5112 match(AddP (DecodeN reg) offset); 5113 op_cost(100); 5114 format %{ "[$reg + $offset]" %} 5115 interface(MEMORY_INTER) %{ 5116 base($reg); 5117 index(0x0); 5118 scale(0x0); 5119 disp($offset); 5120 %} 5121 %} 5122 5123 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5124 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0); 5125 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5126 match(AddP (DecodeNKlass reg) offset); 5127 op_cost(100); 5128 format %{ "[$reg + $offset]" %} 5129 interface(MEMORY_INTER) %{ 5130 base($reg); 5131 index(0x0); 5132 scale(0x0); 5133 disp($offset); 5134 %} 5135 %} 5136 5137 //----------Special Memory Operands-------------------------------------------- 5138 // Stack Slot Operand 5139 // 5140 // This operand is used for loading and storing temporary values on 5141 // the stack where a match requires a value to flow through memory. 5142 operand stackSlotI(sRegI reg) %{ 5143 constraint(ALLOC_IN_RC(stack_slots)); 5144 op_cost(100); 5145 //match(RegI); 5146 format %{ "[sp+$reg]" %} 5147 interface(MEMORY_INTER) %{ 5148 base(0x1); // R1_SP 5149 index(0x0); 5150 scale(0x0); 5151 disp($reg); // Stack Offset 5152 %} 5153 %} 5154 5155 operand stackSlotL(sRegL reg) %{ 5156 constraint(ALLOC_IN_RC(stack_slots)); 5157 op_cost(100); 5158 //match(RegL); 5159 format %{ "[sp+$reg]" %} 5160 interface(MEMORY_INTER) %{ 5161 base(0x1); // R1_SP 5162 index(0x0); 5163 scale(0x0); 5164 disp($reg); // Stack Offset 5165 %} 5166 %} 5167 5168 operand stackSlotP(sRegP reg) %{ 5169 constraint(ALLOC_IN_RC(stack_slots)); 5170 op_cost(100); 5171 //match(RegP); 5172 format %{ "[sp+$reg]" %} 5173 interface(MEMORY_INTER) %{ 5174 base(0x1); // R1_SP 5175 index(0x0); 5176 scale(0x0); 5177 disp($reg); // Stack Offset 5178 %} 5179 %} 5180 5181 operand stackSlotF(sRegF reg) %{ 5182 constraint(ALLOC_IN_RC(stack_slots)); 5183 op_cost(100); 5184 //match(RegF); 5185 format %{ "[sp+$reg]" %} 5186 interface(MEMORY_INTER) %{ 5187 base(0x1); // R1_SP 5188 index(0x0); 5189 scale(0x0); 5190 disp($reg); // Stack Offset 5191 %} 5192 %} 5193 5194 operand stackSlotD(sRegD reg) %{ 5195 constraint(ALLOC_IN_RC(stack_slots)); 5196 op_cost(100); 5197 //match(RegD); 5198 format %{ "[sp+$reg]" %} 5199 interface(MEMORY_INTER) %{ 5200 base(0x1); // R1_SP 5201 index(0x0); 5202 scale(0x0); 5203 disp($reg); // Stack Offset 5204 %} 5205 %} 5206 5207 // Operands for expressing Control Flow 5208 // NOTE: Label is a predefined operand which should not be redefined in 5209 // the AD file. It is generically handled within the ADLC. 5210 5211 //----------Conditional Branch Operands---------------------------------------- 5212 // Comparison Op 5213 // 5214 // This is the operation of the comparison, and is limited to the 5215 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5216 // (!=). 5217 // 5218 // Other attributes of the comparison, such as unsignedness, are specified 5219 // by the comparison instruction that sets a condition code flags register. 5220 // That result is represented by a flags operand whose subtype is appropriate 5221 // to the unsignedness (etc.) of the comparison. 5222 // 5223 // Later, the instruction which matches both the Comparison Op (a Bool) and 5224 // the flags (produced by the Cmp) specifies the coding of the comparison op 5225 // by matching a specific subtype of Bool operand below. 5226 5227 // When used for floating point comparisons: unordered same as less. 5228 operand cmpOp() %{ 5229 match(Bool); 5230 format %{ "" %} 5231 interface(COND_INTER) %{ 5232 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5233 // BO & BI 5234 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5235 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5236 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5237 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5238 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5239 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5240 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5241 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5242 %} 5243 %} 5244 5245 //----------OPERAND CLASSES---------------------------------------------------- 5246 // Operand Classes are groups of operands that are used to simplify 5247 // instruction definitions by not requiring the AD writer to specify 5248 // seperate instructions for every form of operand when the 5249 // instruction accepts multiple operand types with the same basic 5250 // encoding and format. The classic case of this is memory operands. 5251 // Indirect is not included since its use is limited to Compare & Swap. 5252 5253 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5254 // Memory operand where offsets are 4-aligned. Required for ld, std. 5255 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5256 opclass indirectMemory(indirect, indirectNarrow); 5257 5258 // Special opclass for I and ConvL2I. 5259 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5260 5261 // Operand classes to match encode and decode. iRegN_P2N is only used 5262 // for storeN. I have never seen an encode node elsewhere. 5263 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5264 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5265 5266 //----------PIPELINE----------------------------------------------------------- 5267 5268 pipeline %{ 5269 5270 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5271 // J. Res. & Dev., No. 1, Jan. 2002. 5272 5273 //----------ATTRIBUTES--------------------------------------------------------- 5274 attributes %{ 5275 5276 // Power4 instructions are of fixed length. 5277 fixed_size_instructions; 5278 5279 // TODO: if `bundle' means number of instructions fetched 5280 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5281 // max instructions issued per cycle, this is 5. 5282 max_instructions_per_bundle = 8; 5283 5284 // A Power4 instruction is 4 bytes long. 5285 instruction_unit_size = 4; 5286 5287 // The Power4 processor fetches 64 bytes... 5288 instruction_fetch_unit_size = 64; 5289 5290 // ...in one line 5291 instruction_fetch_units = 1 5292 5293 // Unused, list one so that array generated by adlc is not empty. 5294 // Aix compiler chokes if _nop_count = 0. 5295 nops(fxNop); 5296 %} 5297 5298 //----------RESOURCES---------------------------------------------------------- 5299 // Resources are the functional units available to the machine 5300 resources( 5301 PPC_BR, // branch unit 5302 PPC_CR, // condition unit 5303 PPC_FX1, // integer arithmetic unit 1 5304 PPC_FX2, // integer arithmetic unit 2 5305 PPC_LDST1, // load/store unit 1 5306 PPC_LDST2, // load/store unit 2 5307 PPC_FP1, // float arithmetic unit 1 5308 PPC_FP2, // float arithmetic unit 2 5309 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5310 PPC_FX = PPC_FX1 | PPC_FX2, 5311 PPC_FP = PPC_FP1 | PPC_FP2 5312 ); 5313 5314 //----------PIPELINE DESCRIPTION----------------------------------------------- 5315 // Pipeline Description specifies the stages in the machine's pipeline 5316 pipe_desc( 5317 // Power4 longest pipeline path 5318 PPC_IF, // instruction fetch 5319 PPC_IC, 5320 //PPC_BP, // branch prediction 5321 PPC_D0, // decode 5322 PPC_D1, // decode 5323 PPC_D2, // decode 5324 PPC_D3, // decode 5325 PPC_Xfer1, 5326 PPC_GD, // group definition 5327 PPC_MP, // map 5328 PPC_ISS, // issue 5329 PPC_RF, // resource fetch 5330 PPC_EX1, // execute (all units) 5331 PPC_EX2, // execute (FP, LDST) 5332 PPC_EX3, // execute (FP, LDST) 5333 PPC_EX4, // execute (FP) 5334 PPC_EX5, // execute (FP) 5335 PPC_EX6, // execute (FP) 5336 PPC_WB, // write back 5337 PPC_Xfer2, 5338 PPC_CP 5339 ); 5340 5341 //----------PIPELINE CLASSES--------------------------------------------------- 5342 // Pipeline Classes describe the stages in which input and output are 5343 // referenced by the hardware pipeline. 5344 5345 // Simple pipeline classes. 5346 5347 // Default pipeline class. 5348 pipe_class pipe_class_default() %{ 5349 single_instruction; 5350 fixed_latency(2); 5351 %} 5352 5353 // Pipeline class for empty instructions. 5354 pipe_class pipe_class_empty() %{ 5355 single_instruction; 5356 fixed_latency(0); 5357 %} 5358 5359 // Pipeline class for compares. 5360 pipe_class pipe_class_compare() %{ 5361 single_instruction; 5362 fixed_latency(16); 5363 %} 5364 5365 // Pipeline class for traps. 5366 pipe_class pipe_class_trap() %{ 5367 single_instruction; 5368 fixed_latency(100); 5369 %} 5370 5371 // Pipeline class for memory operations. 5372 pipe_class pipe_class_memory() %{ 5373 single_instruction; 5374 fixed_latency(16); 5375 %} 5376 5377 // Pipeline class for call. 5378 pipe_class pipe_class_call() %{ 5379 single_instruction; 5380 fixed_latency(100); 5381 %} 5382 5383 // Define the class for the Nop node. 5384 define %{ 5385 MachNop = pipe_class_default; 5386 %} 5387 5388 %} 5389 5390 //----------INSTRUCTIONS------------------------------------------------------- 5391 5392 // Naming of instructions: 5393 // opA_operB / opA_operB_operC: 5394 // Operation 'op' with one or two source operands 'oper'. Result 5395 // type is A, source operand types are B and C. 5396 // Iff A == B == C, B and C are left out. 5397 // 5398 // The instructions are ordered according to the following scheme: 5399 // - loads 5400 // - load constants 5401 // - prefetch 5402 // - store 5403 // - encode/decode 5404 // - membar 5405 // - conditional moves 5406 // - compare & swap 5407 // - arithmetic and logic operations 5408 // * int: Add, Sub, Mul, Div, Mod 5409 // * int: lShift, arShift, urShift, rot 5410 // * float: Add, Sub, Mul, Div 5411 // * and, or, xor ... 5412 // - register moves: float <-> int, reg <-> stack, repl 5413 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5414 // - conv (low level type cast requiring bit changes (sign extend etc) 5415 // - compares, range & zero checks. 5416 // - branches 5417 // - complex operations, intrinsics, min, max, replicate 5418 // - lock 5419 // - Calls 5420 // 5421 // If there are similar instructions with different types they are sorted: 5422 // int before float 5423 // small before big 5424 // signed before unsigned 5425 // e.g., loadS before loadUS before loadI before loadF. 5426 5427 5428 //----------Load/Store Instructions-------------------------------------------- 5429 5430 //----------Load Instructions-------------------------------------------------- 5431 5432 // Converts byte to int. 5433 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5434 // reuses the 'amount' operand, but adlc expects that operand specification 5435 // and operands in match rule are equivalent. 5436 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5437 effect(DEF dst, USE src); 5438 format %{ "EXTSB $dst, $src \t// byte->int" %} 5439 size(4); 5440 ins_encode %{ 5441 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5442 __ extsb($dst$$Register, $src$$Register); 5443 %} 5444 ins_pipe(pipe_class_default); 5445 %} 5446 5447 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5448 // match-rule, false predicate 5449 match(Set dst (LoadB mem)); 5450 predicate(false); 5451 5452 format %{ "LBZ $dst, $mem" %} 5453 size(4); 5454 ins_encode( enc_lbz(dst, mem) ); 5455 ins_pipe(pipe_class_memory); 5456 %} 5457 5458 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5459 // match-rule, false predicate 5460 match(Set dst (LoadB mem)); 5461 predicate(false); 5462 5463 format %{ "LBZ $dst, $mem\n\t" 5464 "TWI $dst\n\t" 5465 "ISYNC" %} 5466 size(12); 5467 ins_encode( enc_lbz_ac(dst, mem) ); 5468 ins_pipe(pipe_class_memory); 5469 %} 5470 5471 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5472 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5473 match(Set dst (LoadB mem)); 5474 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5475 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5476 expand %{ 5477 iRegIdst tmp; 5478 loadUB_indirect(tmp, mem); 5479 convB2I_reg_2(dst, tmp); 5480 %} 5481 %} 5482 5483 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5484 match(Set dst (LoadB mem)); 5485 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5486 expand %{ 5487 iRegIdst tmp; 5488 loadUB_indirect_ac(tmp, mem); 5489 convB2I_reg_2(dst, tmp); 5490 %} 5491 %} 5492 5493 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5494 // match-rule, false predicate 5495 match(Set dst (LoadB mem)); 5496 predicate(false); 5497 5498 format %{ "LBZ $dst, $mem" %} 5499 size(4); 5500 ins_encode( enc_lbz(dst, mem) ); 5501 ins_pipe(pipe_class_memory); 5502 %} 5503 5504 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5505 // match-rule, false predicate 5506 match(Set dst (LoadB mem)); 5507 predicate(false); 5508 5509 format %{ "LBZ $dst, $mem\n\t" 5510 "TWI $dst\n\t" 5511 "ISYNC" %} 5512 size(12); 5513 ins_encode( enc_lbz_ac(dst, mem) ); 5514 ins_pipe(pipe_class_memory); 5515 %} 5516 5517 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5518 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5519 match(Set dst (LoadB mem)); 5520 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5521 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5522 5523 expand %{ 5524 iRegIdst tmp; 5525 loadUB_indOffset16(tmp, mem); 5526 convB2I_reg_2(dst, tmp); 5527 %} 5528 %} 5529 5530 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5531 match(Set dst (LoadB mem)); 5532 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5533 5534 expand %{ 5535 iRegIdst tmp; 5536 loadUB_indOffset16_ac(tmp, mem); 5537 convB2I_reg_2(dst, tmp); 5538 %} 5539 %} 5540 5541 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5542 instruct loadUB(iRegIdst dst, memory mem) %{ 5543 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5544 match(Set dst (LoadUB mem)); 5545 ins_cost(MEMORY_REF_COST); 5546 5547 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5548 size(4); 5549 ins_encode( enc_lbz(dst, mem) ); 5550 ins_pipe(pipe_class_memory); 5551 %} 5552 5553 // Load Unsigned Byte (8bit UNsigned) acquire. 5554 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5555 match(Set dst (LoadUB mem)); 5556 ins_cost(3*MEMORY_REF_COST); 5557 5558 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5559 "TWI $dst\n\t" 5560 "ISYNC" %} 5561 size(12); 5562 ins_encode( enc_lbz_ac(dst, mem) ); 5563 ins_pipe(pipe_class_memory); 5564 %} 5565 5566 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5567 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5568 match(Set dst (ConvI2L (LoadUB mem))); 5569 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5570 ins_cost(MEMORY_REF_COST); 5571 5572 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5573 size(4); 5574 ins_encode( enc_lbz(dst, mem) ); 5575 ins_pipe(pipe_class_memory); 5576 %} 5577 5578 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5579 match(Set dst (ConvI2L (LoadUB mem))); 5580 ins_cost(3*MEMORY_REF_COST); 5581 5582 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5583 "TWI $dst\n\t" 5584 "ISYNC" %} 5585 size(12); 5586 ins_encode( enc_lbz_ac(dst, mem) ); 5587 ins_pipe(pipe_class_memory); 5588 %} 5589 5590 // Load Short (16bit signed) 5591 instruct loadS(iRegIdst dst, memory mem) %{ 5592 match(Set dst (LoadS mem)); 5593 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5594 ins_cost(MEMORY_REF_COST); 5595 5596 format %{ "LHA $dst, $mem" %} 5597 size(4); 5598 ins_encode %{ 5599 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5600 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5601 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5602 %} 5603 ins_pipe(pipe_class_memory); 5604 %} 5605 5606 // Load Short (16bit signed) acquire. 5607 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5608 match(Set dst (LoadS mem)); 5609 ins_cost(3*MEMORY_REF_COST); 5610 5611 format %{ "LHA $dst, $mem\t acquire\n\t" 5612 "TWI $dst\n\t" 5613 "ISYNC" %} 5614 size(12); 5615 ins_encode %{ 5616 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5617 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5618 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5619 __ twi_0($dst$$Register); 5620 __ isync(); 5621 %} 5622 ins_pipe(pipe_class_memory); 5623 %} 5624 5625 // Load Char (16bit unsigned) 5626 instruct loadUS(iRegIdst dst, memory mem) %{ 5627 match(Set dst (LoadUS mem)); 5628 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5629 ins_cost(MEMORY_REF_COST); 5630 5631 format %{ "LHZ $dst, $mem" %} 5632 size(4); 5633 ins_encode( enc_lhz(dst, mem) ); 5634 ins_pipe(pipe_class_memory); 5635 %} 5636 5637 // Load Char (16bit unsigned) acquire. 5638 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5639 match(Set dst (LoadUS mem)); 5640 ins_cost(3*MEMORY_REF_COST); 5641 5642 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5643 "TWI $dst\n\t" 5644 "ISYNC" %} 5645 size(12); 5646 ins_encode( enc_lhz_ac(dst, mem) ); 5647 ins_pipe(pipe_class_memory); 5648 %} 5649 5650 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5651 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5652 match(Set dst (ConvI2L (LoadUS mem))); 5653 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5654 ins_cost(MEMORY_REF_COST); 5655 5656 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5657 size(4); 5658 ins_encode( enc_lhz(dst, mem) ); 5659 ins_pipe(pipe_class_memory); 5660 %} 5661 5662 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5663 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5664 match(Set dst (ConvI2L (LoadUS mem))); 5665 ins_cost(3*MEMORY_REF_COST); 5666 5667 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5668 "TWI $dst\n\t" 5669 "ISYNC" %} 5670 size(12); 5671 ins_encode( enc_lhz_ac(dst, mem) ); 5672 ins_pipe(pipe_class_memory); 5673 %} 5674 5675 // Load Integer. 5676 instruct loadI(iRegIdst dst, memory mem) %{ 5677 match(Set dst (LoadI mem)); 5678 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5679 ins_cost(MEMORY_REF_COST); 5680 5681 format %{ "LWZ $dst, $mem" %} 5682 size(4); 5683 ins_encode( enc_lwz(dst, mem) ); 5684 ins_pipe(pipe_class_memory); 5685 %} 5686 5687 // Load Integer acquire. 5688 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5689 match(Set dst (LoadI mem)); 5690 ins_cost(3*MEMORY_REF_COST); 5691 5692 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5693 "TWI $dst\n\t" 5694 "ISYNC" %} 5695 size(12); 5696 ins_encode( enc_lwz_ac(dst, mem) ); 5697 ins_pipe(pipe_class_memory); 5698 %} 5699 5700 // Match loading integer and casting it to unsigned int in 5701 // long register. 5702 // LoadI + ConvI2L + AndL 0xffffffff. 5703 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5704 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5705 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5706 ins_cost(MEMORY_REF_COST); 5707 5708 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5709 size(4); 5710 ins_encode( enc_lwz(dst, mem) ); 5711 ins_pipe(pipe_class_memory); 5712 %} 5713 5714 // Match loading integer and casting it to long. 5715 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5716 match(Set dst (ConvI2L (LoadI mem))); 5717 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5718 ins_cost(MEMORY_REF_COST); 5719 5720 format %{ "LWA $dst, $mem \t// loadI2L" %} 5721 size(4); 5722 ins_encode %{ 5723 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5724 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5725 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5726 %} 5727 ins_pipe(pipe_class_memory); 5728 %} 5729 5730 // Match loading integer and casting it to long - acquire. 5731 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5732 match(Set dst (ConvI2L (LoadI mem))); 5733 ins_cost(3*MEMORY_REF_COST); 5734 5735 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5736 "TWI $dst\n\t" 5737 "ISYNC" %} 5738 size(12); 5739 ins_encode %{ 5740 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5741 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5742 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5743 __ twi_0($dst$$Register); 5744 __ isync(); 5745 %} 5746 ins_pipe(pipe_class_memory); 5747 %} 5748 5749 // Load Long - aligned 5750 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5751 match(Set dst (LoadL mem)); 5752 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5753 ins_cost(MEMORY_REF_COST); 5754 5755 format %{ "LD $dst, $mem \t// long" %} 5756 size(4); 5757 ins_encode( enc_ld(dst, mem) ); 5758 ins_pipe(pipe_class_memory); 5759 %} 5760 5761 // Load Long - aligned acquire. 5762 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5763 match(Set dst (LoadL mem)); 5764 ins_cost(3*MEMORY_REF_COST); 5765 5766 format %{ "LD $dst, $mem \t// long acquire\n\t" 5767 "TWI $dst\n\t" 5768 "ISYNC" %} 5769 size(12); 5770 ins_encode( enc_ld_ac(dst, mem) ); 5771 ins_pipe(pipe_class_memory); 5772 %} 5773 5774 // Load Long - UNaligned 5775 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5776 match(Set dst (LoadL_unaligned mem)); 5777 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5778 ins_cost(MEMORY_REF_COST); 5779 5780 format %{ "LD $dst, $mem \t// unaligned long" %} 5781 size(4); 5782 ins_encode( enc_ld(dst, mem) ); 5783 ins_pipe(pipe_class_memory); 5784 %} 5785 5786 // Load nodes for superwords 5787 5788 // Load Aligned Packed Byte 5789 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5790 predicate(n->as_LoadVector()->memory_size() == 8); 5791 match(Set dst (LoadVector mem)); 5792 ins_cost(MEMORY_REF_COST); 5793 5794 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5795 size(4); 5796 ins_encode( enc_ld(dst, mem) ); 5797 ins_pipe(pipe_class_memory); 5798 %} 5799 5800 // Load Aligned Packed Byte 5801 instruct loadV16(vecX dst, indirect mem) %{ 5802 predicate(n->as_LoadVector()->memory_size() == 16); 5803 match(Set dst (LoadVector mem)); 5804 ins_cost(MEMORY_REF_COST); 5805 5806 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5807 size(4); 5808 ins_encode %{ 5809 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5810 %} 5811 ins_pipe(pipe_class_default); 5812 %} 5813 5814 // Load Range, range = array length (=jint) 5815 instruct loadRange(iRegIdst dst, memory mem) %{ 5816 match(Set dst (LoadRange mem)); 5817 ins_cost(MEMORY_REF_COST); 5818 5819 format %{ "LWZ $dst, $mem \t// range" %} 5820 size(4); 5821 ins_encode( enc_lwz(dst, mem) ); 5822 ins_pipe(pipe_class_memory); 5823 %} 5824 5825 // Load Compressed Pointer 5826 instruct loadN(iRegNdst dst, memory mem) %{ 5827 match(Set dst (LoadN mem)); 5828 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5829 ins_cost(MEMORY_REF_COST); 5830 5831 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5832 size(4); 5833 ins_encode( enc_lwz(dst, mem) ); 5834 ins_pipe(pipe_class_memory); 5835 %} 5836 5837 // Load Compressed Pointer acquire. 5838 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5839 match(Set dst (LoadN mem)); 5840 ins_cost(3*MEMORY_REF_COST); 5841 5842 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5843 "TWI $dst\n\t" 5844 "ISYNC" %} 5845 size(12); 5846 ins_encode( enc_lwz_ac(dst, mem) ); 5847 ins_pipe(pipe_class_memory); 5848 %} 5849 5850 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5851 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5852 match(Set dst (DecodeN (LoadN mem))); 5853 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && CompressedOops::shift() == 0); 5854 ins_cost(MEMORY_REF_COST); 5855 5856 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5857 size(4); 5858 ins_encode( enc_lwz(dst, mem) ); 5859 ins_pipe(pipe_class_memory); 5860 %} 5861 5862 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5863 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5864 predicate(CompressedKlassPointers::base() == NULL && CompressedKlassPointers::shift() == 0 && 5865 _kids[0]->_leaf->as_Load()->is_unordered()); 5866 ins_cost(MEMORY_REF_COST); 5867 5868 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5869 size(4); 5870 ins_encode( enc_lwz(dst, mem) ); 5871 ins_pipe(pipe_class_memory); 5872 %} 5873 5874 // Load Pointer 5875 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5876 match(Set dst (LoadP mem)); 5877 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5878 ins_cost(MEMORY_REF_COST); 5879 5880 format %{ "LD $dst, $mem \t// ptr" %} 5881 size(4); 5882 ins_encode( enc_ld(dst, mem) ); 5883 ins_pipe(pipe_class_memory); 5884 %} 5885 5886 // Load Pointer acquire. 5887 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5888 match(Set dst (LoadP mem)); 5889 ins_cost(3*MEMORY_REF_COST); 5890 5891 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5892 "TWI $dst\n\t" 5893 "ISYNC" %} 5894 size(12); 5895 ins_encode( enc_ld_ac(dst, mem) ); 5896 ins_pipe(pipe_class_memory); 5897 %} 5898 5899 // LoadP + CastP2L 5900 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5901 match(Set dst (CastP2X (LoadP mem))); 5902 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5903 ins_cost(MEMORY_REF_COST); 5904 5905 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5906 size(4); 5907 ins_encode( enc_ld(dst, mem) ); 5908 ins_pipe(pipe_class_memory); 5909 %} 5910 5911 // Load compressed klass pointer. 5912 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5913 match(Set dst (LoadNKlass mem)); 5914 ins_cost(MEMORY_REF_COST); 5915 5916 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5917 size(4); 5918 ins_encode( enc_lwz(dst, mem) ); 5919 ins_pipe(pipe_class_memory); 5920 %} 5921 5922 // Load Klass Pointer 5923 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5924 match(Set dst (LoadKlass mem)); 5925 ins_cost(MEMORY_REF_COST); 5926 5927 format %{ "LD $dst, $mem \t// klass ptr" %} 5928 size(4); 5929 ins_encode( enc_ld(dst, mem) ); 5930 ins_pipe(pipe_class_memory); 5931 %} 5932 5933 // Load Float 5934 instruct loadF(regF dst, memory mem) %{ 5935 match(Set dst (LoadF mem)); 5936 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5937 ins_cost(MEMORY_REF_COST); 5938 5939 format %{ "LFS $dst, $mem" %} 5940 size(4); 5941 ins_encode %{ 5942 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5943 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5944 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5945 %} 5946 ins_pipe(pipe_class_memory); 5947 %} 5948 5949 // Load Float acquire. 5950 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5951 match(Set dst (LoadF mem)); 5952 effect(TEMP cr0); 5953 ins_cost(3*MEMORY_REF_COST); 5954 5955 format %{ "LFS $dst, $mem \t// acquire\n\t" 5956 "FCMPU cr0, $dst, $dst\n\t" 5957 "BNE cr0, next\n" 5958 "next:\n\t" 5959 "ISYNC" %} 5960 size(16); 5961 ins_encode %{ 5962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5963 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5964 Label next; 5965 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5966 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5967 __ bne(CCR0, next); 5968 __ bind(next); 5969 __ isync(); 5970 %} 5971 ins_pipe(pipe_class_memory); 5972 %} 5973 5974 // Load Double - aligned 5975 instruct loadD(regD dst, memory mem) %{ 5976 match(Set dst (LoadD mem)); 5977 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5978 ins_cost(MEMORY_REF_COST); 5979 5980 format %{ "LFD $dst, $mem" %} 5981 size(4); 5982 ins_encode( enc_lfd(dst, mem) ); 5983 ins_pipe(pipe_class_memory); 5984 %} 5985 5986 // Load Double - aligned acquire. 5987 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5988 match(Set dst (LoadD mem)); 5989 effect(TEMP cr0); 5990 ins_cost(3*MEMORY_REF_COST); 5991 5992 format %{ "LFD $dst, $mem \t// acquire\n\t" 5993 "FCMPU cr0, $dst, $dst\n\t" 5994 "BNE cr0, next\n" 5995 "next:\n\t" 5996 "ISYNC" %} 5997 size(16); 5998 ins_encode %{ 5999 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6000 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6001 Label next; 6002 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 6003 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 6004 __ bne(CCR0, next); 6005 __ bind(next); 6006 __ isync(); 6007 %} 6008 ins_pipe(pipe_class_memory); 6009 %} 6010 6011 // Load Double - UNaligned 6012 instruct loadD_unaligned(regD dst, memory mem) %{ 6013 match(Set dst (LoadD_unaligned mem)); 6014 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 6015 ins_cost(MEMORY_REF_COST); 6016 6017 format %{ "LFD $dst, $mem" %} 6018 size(4); 6019 ins_encode( enc_lfd(dst, mem) ); 6020 ins_pipe(pipe_class_memory); 6021 %} 6022 6023 //----------Constants-------------------------------------------------------- 6024 6025 // Load MachConstantTableBase: add hi offset to global toc. 6026 // TODO: Handle hidden register r29 in bundler! 6027 instruct loadToc_hi(iRegLdst dst) %{ 6028 effect(DEF dst); 6029 ins_cost(DEFAULT_COST); 6030 6031 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6032 size(4); 6033 ins_encode %{ 6034 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6035 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6036 %} 6037 ins_pipe(pipe_class_default); 6038 %} 6039 6040 // Load MachConstantTableBase: add lo offset to global toc. 6041 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6042 effect(DEF dst, USE src); 6043 ins_cost(DEFAULT_COST); 6044 6045 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6046 size(4); 6047 ins_encode %{ 6048 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6049 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6050 %} 6051 ins_pipe(pipe_class_default); 6052 %} 6053 6054 // Load 16-bit integer constant 0xssss???? 6055 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6056 match(Set dst src); 6057 6058 format %{ "LI $dst, $src" %} 6059 size(4); 6060 ins_encode %{ 6061 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6062 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6063 %} 6064 ins_pipe(pipe_class_default); 6065 %} 6066 6067 // Load integer constant 0x????0000 6068 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6069 match(Set dst src); 6070 ins_cost(DEFAULT_COST); 6071 6072 format %{ "LIS $dst, $src.hi" %} 6073 size(4); 6074 ins_encode %{ 6075 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6076 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6077 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6078 %} 6079 ins_pipe(pipe_class_default); 6080 %} 6081 6082 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6083 // and sign extended), this adds the low 16 bits. 6084 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6085 // no match-rule, false predicate 6086 effect(DEF dst, USE src1, USE src2); 6087 predicate(false); 6088 6089 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6090 size(4); 6091 ins_encode %{ 6092 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6093 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6094 %} 6095 ins_pipe(pipe_class_default); 6096 %} 6097 6098 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6099 match(Set dst src); 6100 ins_cost(DEFAULT_COST*2); 6101 6102 expand %{ 6103 // Would like to use $src$$constant. 6104 immI16 srcLo %{ _opnds[1]->constant() %} 6105 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6106 immIhi16 srcHi %{ _opnds[1]->constant() %} 6107 iRegIdst tmpI; 6108 loadConIhi16(tmpI, srcHi); 6109 loadConI32_lo16(dst, tmpI, srcLo); 6110 %} 6111 %} 6112 6113 // No constant pool entries required. 6114 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6115 match(Set dst src); 6116 6117 format %{ "LI $dst, $src \t// long" %} 6118 size(4); 6119 ins_encode %{ 6120 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6121 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6122 %} 6123 ins_pipe(pipe_class_default); 6124 %} 6125 6126 // Load long constant 0xssssssss????0000 6127 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6128 match(Set dst src); 6129 ins_cost(DEFAULT_COST); 6130 6131 format %{ "LIS $dst, $src.hi \t// long" %} 6132 size(4); 6133 ins_encode %{ 6134 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6135 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6136 %} 6137 ins_pipe(pipe_class_default); 6138 %} 6139 6140 // To load a 32 bit constant: merge lower 16 bits into already loaded 6141 // high 16 bits. 6142 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6143 // no match-rule, false predicate 6144 effect(DEF dst, USE src1, USE src2); 6145 predicate(false); 6146 6147 format %{ "ORI $dst, $src1, $src2.lo" %} 6148 size(4); 6149 ins_encode %{ 6150 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6151 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6152 %} 6153 ins_pipe(pipe_class_default); 6154 %} 6155 6156 // Load 32-bit long constant 6157 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6158 match(Set dst src); 6159 ins_cost(DEFAULT_COST*2); 6160 6161 expand %{ 6162 // Would like to use $src$$constant. 6163 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6164 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6165 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6166 iRegLdst tmpL; 6167 loadConL32hi16(tmpL, srcHi); 6168 loadConL32_lo16(dst, tmpL, srcLo); 6169 %} 6170 %} 6171 6172 // Load long constant 0x????000000000000. 6173 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6174 match(Set dst src); 6175 ins_cost(DEFAULT_COST); 6176 6177 expand %{ 6178 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6179 immI shift32 %{ 32 %} 6180 iRegLdst tmpL; 6181 loadConL32hi16(tmpL, srcHi); 6182 lshiftL_regL_immI(dst, tmpL, shift32); 6183 %} 6184 %} 6185 6186 // Expand node for constant pool load: small offset. 6187 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6188 effect(DEF dst, USE src, USE toc); 6189 ins_cost(MEMORY_REF_COST); 6190 6191 ins_num_consts(1); 6192 // Needed so that CallDynamicJavaDirect can compute the address of this 6193 // instruction for relocation. 6194 ins_field_cbuf_insts_offset(int); 6195 6196 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6197 size(4); 6198 ins_encode( enc_load_long_constL(dst, src, toc) ); 6199 ins_pipe(pipe_class_memory); 6200 %} 6201 6202 // Expand node for constant pool load: large offset. 6203 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6204 effect(DEF dst, USE src, USE toc); 6205 predicate(false); 6206 6207 ins_num_consts(1); 6208 ins_field_const_toc_offset(int); 6209 // Needed so that CallDynamicJavaDirect can compute the address of this 6210 // instruction for relocation. 6211 ins_field_cbuf_insts_offset(int); 6212 6213 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6214 size(4); 6215 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6216 ins_pipe(pipe_class_default); 6217 %} 6218 6219 // Expand node for constant pool load: large offset. 6220 // No constant pool entries required. 6221 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6222 effect(DEF dst, USE src, USE base); 6223 predicate(false); 6224 6225 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6226 6227 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6228 size(4); 6229 ins_encode %{ 6230 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6231 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6232 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6233 %} 6234 ins_pipe(pipe_class_memory); 6235 %} 6236 6237 // Load long constant from constant table. Expand in case of 6238 // offset > 16 bit is needed. 6239 // Adlc adds toc node MachConstantTableBase. 6240 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6241 match(Set dst src); 6242 ins_cost(MEMORY_REF_COST); 6243 6244 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6245 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6246 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6247 %} 6248 6249 // Load NULL as compressed oop. 6250 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6251 match(Set dst src); 6252 ins_cost(DEFAULT_COST); 6253 6254 format %{ "LI $dst, $src \t// compressed ptr" %} 6255 size(4); 6256 ins_encode %{ 6257 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6258 __ li($dst$$Register, 0); 6259 %} 6260 ins_pipe(pipe_class_default); 6261 %} 6262 6263 // Load hi part of compressed oop constant. 6264 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6265 effect(DEF dst, USE src); 6266 ins_cost(DEFAULT_COST); 6267 6268 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6269 size(4); 6270 ins_encode %{ 6271 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6272 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6273 %} 6274 ins_pipe(pipe_class_default); 6275 %} 6276 6277 // Add lo part of compressed oop constant to already loaded hi part. 6278 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6279 effect(DEF dst, USE src1, USE src2); 6280 ins_cost(DEFAULT_COST); 6281 6282 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6283 size(4); 6284 ins_encode %{ 6285 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6286 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6287 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6288 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6289 __ relocate(rspec, 1); 6290 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6291 %} 6292 ins_pipe(pipe_class_default); 6293 %} 6294 6295 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6296 effect(DEF dst, USE src, USE shift, USE mask_begin); 6297 6298 size(4); 6299 ins_encode %{ 6300 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6301 %} 6302 ins_pipe(pipe_class_default); 6303 %} 6304 6305 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6306 // leaving the upper 32 bits with sign-extension bits. 6307 // This clears these bits: dst = src & 0xFFFFFFFF. 6308 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6309 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6310 effect(DEF dst, USE src); 6311 predicate(false); 6312 6313 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6314 size(4); 6315 ins_encode %{ 6316 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6317 __ clrldi($dst$$Register, $src$$Register, 0x20); 6318 %} 6319 ins_pipe(pipe_class_default); 6320 %} 6321 6322 // Optimize DecodeN for disjoint base. 6323 // Load base of compressed oops into a register 6324 instruct loadBase(iRegLdst dst) %{ 6325 effect(DEF dst); 6326 6327 format %{ "LoadConst $dst, heapbase" %} 6328 ins_encode %{ 6329 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6330 __ load_const_optimized($dst$$Register, CompressedOops::base(), R0); 6331 %} 6332 ins_pipe(pipe_class_default); 6333 %} 6334 6335 // Loading ConN must be postalloc expanded so that edges between 6336 // the nodes are safe. They may not interfere with a safepoint. 6337 // GL TODO: This needs three instructions: better put this into the constant pool. 6338 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6339 match(Set dst src); 6340 ins_cost(DEFAULT_COST*2); 6341 6342 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6343 postalloc_expand %{ 6344 MachNode *m1 = new loadConN_hiNode(); 6345 MachNode *m2 = new loadConN_loNode(); 6346 MachNode *m3 = new clearMs32bNode(); 6347 m1->add_req(NULL); 6348 m2->add_req(NULL, m1); 6349 m3->add_req(NULL, m2); 6350 m1->_opnds[0] = op_dst; 6351 m1->_opnds[1] = op_src; 6352 m2->_opnds[0] = op_dst; 6353 m2->_opnds[1] = op_dst; 6354 m2->_opnds[2] = op_src; 6355 m3->_opnds[0] = op_dst; 6356 m3->_opnds[1] = op_dst; 6357 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6358 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6359 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6360 nodes->push(m1); 6361 nodes->push(m2); 6362 nodes->push(m3); 6363 %} 6364 %} 6365 6366 // We have seen a safepoint between the hi and lo parts, and this node was handled 6367 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6368 // not a narrow oop. 6369 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6370 match(Set dst src); 6371 effect(DEF dst, USE src); 6372 ins_cost(DEFAULT_COST); 6373 6374 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6375 size(4); 6376 ins_encode %{ 6377 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6378 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant); 6379 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6380 %} 6381 ins_pipe(pipe_class_default); 6382 %} 6383 6384 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6385 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6386 match(Set dst src1); 6387 effect(TEMP src2); 6388 ins_cost(DEFAULT_COST); 6389 6390 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6391 size(4); 6392 ins_encode %{ 6393 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6394 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6395 %} 6396 ins_pipe(pipe_class_default); 6397 %} 6398 6399 // This needs a match rule so that build_oop_map knows this is 6400 // not a narrow oop. 6401 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6402 match(Set dst src1); 6403 effect(TEMP src2); 6404 ins_cost(DEFAULT_COST); 6405 6406 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6407 size(4); 6408 ins_encode %{ 6409 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6410 intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant); 6411 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6412 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6413 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6414 6415 __ relocate(rspec, 1); 6416 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6417 %} 6418 ins_pipe(pipe_class_default); 6419 %} 6420 6421 // Loading ConNKlass must be postalloc expanded so that edges between 6422 // the nodes are safe. They may not interfere with a safepoint. 6423 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6424 match(Set dst src); 6425 ins_cost(DEFAULT_COST*2); 6426 6427 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6428 postalloc_expand %{ 6429 // Load high bits into register. Sign extended. 6430 MachNode *m1 = new loadConNKlass_hiNode(); 6431 m1->add_req(NULL); 6432 m1->_opnds[0] = op_dst; 6433 m1->_opnds[1] = op_src; 6434 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6435 nodes->push(m1); 6436 6437 MachNode *m2 = m1; 6438 if (!Assembler::is_uimm((jlong)CompressedKlassPointers::encode((Klass *)op_src->constant()), 31)) { 6439 // Value might be 1-extended. Mask out these bits. 6440 m2 = new loadConNKlass_maskNode(); 6441 m2->add_req(NULL, m1); 6442 m2->_opnds[0] = op_dst; 6443 m2->_opnds[1] = op_src; 6444 m2->_opnds[2] = op_dst; 6445 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6446 nodes->push(m2); 6447 } 6448 6449 MachNode *m3 = new loadConNKlass_loNode(); 6450 m3->add_req(NULL, m2); 6451 m3->_opnds[0] = op_dst; 6452 m3->_opnds[1] = op_src; 6453 m3->_opnds[2] = op_dst; 6454 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6455 nodes->push(m3); 6456 %} 6457 %} 6458 6459 // 0x1 is used in object initialization (initial object header). 6460 // No constant pool entries required. 6461 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6462 match(Set dst src); 6463 6464 format %{ "LI $dst, $src \t// ptr" %} 6465 size(4); 6466 ins_encode %{ 6467 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6468 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6469 %} 6470 ins_pipe(pipe_class_default); 6471 %} 6472 6473 // Expand node for constant pool load: small offset. 6474 // The match rule is needed to generate the correct bottom_type(), 6475 // however this node should never match. The use of predicate is not 6476 // possible since ADLC forbids predicates for chain rules. The higher 6477 // costs do not prevent matching in this case. For that reason the 6478 // operand immP_NM with predicate(false) is used. 6479 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6480 match(Set dst src); 6481 effect(TEMP toc); 6482 6483 ins_num_consts(1); 6484 6485 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6486 size(4); 6487 ins_encode( enc_load_long_constP(dst, src, toc) ); 6488 ins_pipe(pipe_class_memory); 6489 %} 6490 6491 // Expand node for constant pool load: large offset. 6492 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6493 effect(DEF dst, USE src, USE toc); 6494 predicate(false); 6495 6496 ins_num_consts(1); 6497 ins_field_const_toc_offset(int); 6498 6499 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6500 size(4); 6501 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6502 ins_pipe(pipe_class_default); 6503 %} 6504 6505 // Expand node for constant pool load: large offset. 6506 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6507 match(Set dst src); 6508 effect(TEMP base); 6509 6510 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6511 6512 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6513 size(4); 6514 ins_encode %{ 6515 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6516 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6517 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6518 %} 6519 ins_pipe(pipe_class_memory); 6520 %} 6521 6522 // Load pointer constant from constant table. Expand in case an 6523 // offset > 16 bit is needed. 6524 // Adlc adds toc node MachConstantTableBase. 6525 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6526 match(Set dst src); 6527 ins_cost(MEMORY_REF_COST); 6528 6529 // This rule does not use "expand" because then 6530 // the result type is not known to be an Oop. An ADLC 6531 // enhancement will be needed to make that work - not worth it! 6532 6533 // If this instruction rematerializes, it prolongs the live range 6534 // of the toc node, causing illegal graphs. 6535 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6536 ins_cannot_rematerialize(true); 6537 6538 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6539 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6540 %} 6541 6542 // Expand node for constant pool load: small offset. 6543 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6544 effect(DEF dst, USE src, USE toc); 6545 ins_cost(MEMORY_REF_COST); 6546 6547 ins_num_consts(1); 6548 6549 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6550 size(4); 6551 ins_encode %{ 6552 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6553 address float_address = __ float_constant($src$$constant); 6554 if (float_address == NULL) { 6555 ciEnv::current()->record_out_of_memory_failure(); 6556 return; 6557 } 6558 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6559 %} 6560 ins_pipe(pipe_class_memory); 6561 %} 6562 6563 // Expand node for constant pool load: large offset. 6564 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6565 effect(DEF dst, USE src, USE toc); 6566 ins_cost(MEMORY_REF_COST); 6567 6568 ins_num_consts(1); 6569 6570 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6571 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6572 "ADDIS $toc, $toc, -offset_hi"%} 6573 size(12); 6574 ins_encode %{ 6575 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6576 FloatRegister Rdst = $dst$$FloatRegister; 6577 Register Rtoc = $toc$$Register; 6578 address float_address = __ float_constant($src$$constant); 6579 if (float_address == NULL) { 6580 ciEnv::current()->record_out_of_memory_failure(); 6581 return; 6582 } 6583 int offset = __ offset_to_method_toc(float_address); 6584 int hi = (offset + (1<<15))>>16; 6585 int lo = offset - hi * (1<<16); 6586 6587 __ addis(Rtoc, Rtoc, hi); 6588 __ lfs(Rdst, lo, Rtoc); 6589 __ addis(Rtoc, Rtoc, -hi); 6590 %} 6591 ins_pipe(pipe_class_memory); 6592 %} 6593 6594 // Adlc adds toc node MachConstantTableBase. 6595 instruct loadConF_Ex(regF dst, immF src) %{ 6596 match(Set dst src); 6597 ins_cost(MEMORY_REF_COST); 6598 6599 // See loadConP. 6600 ins_cannot_rematerialize(true); 6601 6602 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6603 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6604 %} 6605 6606 // Expand node for constant pool load: small offset. 6607 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6608 effect(DEF dst, USE src, USE toc); 6609 ins_cost(MEMORY_REF_COST); 6610 6611 ins_num_consts(1); 6612 6613 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6614 size(4); 6615 ins_encode %{ 6616 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6617 address float_address = __ double_constant($src$$constant); 6618 if (float_address == NULL) { 6619 ciEnv::current()->record_out_of_memory_failure(); 6620 return; 6621 } 6622 int offset = __ offset_to_method_toc(float_address); 6623 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6624 %} 6625 ins_pipe(pipe_class_memory); 6626 %} 6627 6628 // Expand node for constant pool load: large offset. 6629 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6630 effect(DEF dst, USE src, USE toc); 6631 ins_cost(MEMORY_REF_COST); 6632 6633 ins_num_consts(1); 6634 6635 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6636 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6637 "ADDIS $toc, $toc, -offset_hi" %} 6638 size(12); 6639 ins_encode %{ 6640 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6641 FloatRegister Rdst = $dst$$FloatRegister; 6642 Register Rtoc = $toc$$Register; 6643 address float_address = __ double_constant($src$$constant); 6644 if (float_address == NULL) { 6645 ciEnv::current()->record_out_of_memory_failure(); 6646 return; 6647 } 6648 int offset = __ offset_to_method_toc(float_address); 6649 int hi = (offset + (1<<15))>>16; 6650 int lo = offset - hi * (1<<16); 6651 6652 __ addis(Rtoc, Rtoc, hi); 6653 __ lfd(Rdst, lo, Rtoc); 6654 __ addis(Rtoc, Rtoc, -hi); 6655 %} 6656 ins_pipe(pipe_class_memory); 6657 %} 6658 6659 // Adlc adds toc node MachConstantTableBase. 6660 instruct loadConD_Ex(regD dst, immD src) %{ 6661 match(Set dst src); 6662 ins_cost(MEMORY_REF_COST); 6663 6664 // See loadConP. 6665 ins_cannot_rematerialize(true); 6666 6667 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6668 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6669 %} 6670 6671 // Prefetch instructions. 6672 // Must be safe to execute with invalid address (cannot fault). 6673 6674 // Special prefetch versions which use the dcbz instruction. 6675 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6676 match(PrefetchAllocation (AddP mem src)); 6677 predicate(AllocatePrefetchStyle == 3); 6678 ins_cost(MEMORY_REF_COST); 6679 6680 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6681 size(4); 6682 ins_encode %{ 6683 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6684 __ dcbz($src$$Register, $mem$$base$$Register); 6685 %} 6686 ins_pipe(pipe_class_memory); 6687 %} 6688 6689 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6690 match(PrefetchAllocation mem); 6691 predicate(AllocatePrefetchStyle == 3); 6692 ins_cost(MEMORY_REF_COST); 6693 6694 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6695 size(4); 6696 ins_encode %{ 6697 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6698 __ dcbz($mem$$base$$Register); 6699 %} 6700 ins_pipe(pipe_class_memory); 6701 %} 6702 6703 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6704 match(PrefetchAllocation (AddP mem src)); 6705 predicate(AllocatePrefetchStyle != 3); 6706 ins_cost(MEMORY_REF_COST); 6707 6708 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6709 size(4); 6710 ins_encode %{ 6711 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6712 __ dcbtst($src$$Register, $mem$$base$$Register); 6713 %} 6714 ins_pipe(pipe_class_memory); 6715 %} 6716 6717 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6718 match(PrefetchAllocation mem); 6719 predicate(AllocatePrefetchStyle != 3); 6720 ins_cost(MEMORY_REF_COST); 6721 6722 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6723 size(4); 6724 ins_encode %{ 6725 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6726 __ dcbtst($mem$$base$$Register); 6727 %} 6728 ins_pipe(pipe_class_memory); 6729 %} 6730 6731 //----------Store Instructions------------------------------------------------- 6732 6733 // Store Byte 6734 instruct storeB(memory mem, iRegIsrc src) %{ 6735 match(Set mem (StoreB mem src)); 6736 ins_cost(MEMORY_REF_COST); 6737 6738 format %{ "STB $src, $mem \t// byte" %} 6739 size(4); 6740 ins_encode %{ 6741 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6742 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6743 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6744 %} 6745 ins_pipe(pipe_class_memory); 6746 %} 6747 6748 // Store Char/Short 6749 instruct storeC(memory mem, iRegIsrc src) %{ 6750 match(Set mem (StoreC mem src)); 6751 ins_cost(MEMORY_REF_COST); 6752 6753 format %{ "STH $src, $mem \t// short" %} 6754 size(4); 6755 ins_encode %{ 6756 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6757 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6758 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6759 %} 6760 ins_pipe(pipe_class_memory); 6761 %} 6762 6763 // Store Integer 6764 instruct storeI(memory mem, iRegIsrc src) %{ 6765 match(Set mem (StoreI mem src)); 6766 ins_cost(MEMORY_REF_COST); 6767 6768 format %{ "STW $src, $mem" %} 6769 size(4); 6770 ins_encode( enc_stw(src, mem) ); 6771 ins_pipe(pipe_class_memory); 6772 %} 6773 6774 // ConvL2I + StoreI. 6775 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6776 match(Set mem (StoreI mem (ConvL2I src))); 6777 ins_cost(MEMORY_REF_COST); 6778 6779 format %{ "STW l2i($src), $mem" %} 6780 size(4); 6781 ins_encode( enc_stw(src, mem) ); 6782 ins_pipe(pipe_class_memory); 6783 %} 6784 6785 // Store Long 6786 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6787 match(Set mem (StoreL mem src)); 6788 ins_cost(MEMORY_REF_COST); 6789 6790 format %{ "STD $src, $mem \t// long" %} 6791 size(4); 6792 ins_encode( enc_std(src, mem) ); 6793 ins_pipe(pipe_class_memory); 6794 %} 6795 6796 // Store super word nodes. 6797 6798 // Store Aligned Packed Byte long register to memory 6799 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6800 predicate(n->as_StoreVector()->memory_size() == 8); 6801 match(Set mem (StoreVector mem src)); 6802 ins_cost(MEMORY_REF_COST); 6803 6804 format %{ "STD $mem, $src \t// packed8B" %} 6805 size(4); 6806 ins_encode( enc_std(src, mem) ); 6807 ins_pipe(pipe_class_memory); 6808 %} 6809 6810 // Store Packed Byte long register to memory 6811 instruct storeV16(indirect mem, vecX src) %{ 6812 predicate(n->as_StoreVector()->memory_size() == 16); 6813 match(Set mem (StoreVector mem src)); 6814 ins_cost(MEMORY_REF_COST); 6815 6816 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6817 size(4); 6818 ins_encode %{ 6819 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6820 %} 6821 ins_pipe(pipe_class_default); 6822 %} 6823 6824 // Store Compressed Oop 6825 instruct storeN(memory dst, iRegN_P2N src) %{ 6826 match(Set dst (StoreN dst src)); 6827 ins_cost(MEMORY_REF_COST); 6828 6829 format %{ "STW $src, $dst \t// compressed oop" %} 6830 size(4); 6831 ins_encode( enc_stw(src, dst) ); 6832 ins_pipe(pipe_class_memory); 6833 %} 6834 6835 // Store Compressed KLass 6836 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6837 match(Set dst (StoreNKlass dst src)); 6838 ins_cost(MEMORY_REF_COST); 6839 6840 format %{ "STW $src, $dst \t// compressed klass" %} 6841 size(4); 6842 ins_encode( enc_stw(src, dst) ); 6843 ins_pipe(pipe_class_memory); 6844 %} 6845 6846 // Store Pointer 6847 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6848 match(Set dst (StoreP dst src)); 6849 ins_cost(MEMORY_REF_COST); 6850 6851 format %{ "STD $src, $dst \t// ptr" %} 6852 size(4); 6853 ins_encode( enc_std(src, dst) ); 6854 ins_pipe(pipe_class_memory); 6855 %} 6856 6857 // Store Float 6858 instruct storeF(memory mem, regF src) %{ 6859 match(Set mem (StoreF mem src)); 6860 ins_cost(MEMORY_REF_COST); 6861 6862 format %{ "STFS $src, $mem" %} 6863 size(4); 6864 ins_encode( enc_stfs(src, mem) ); 6865 ins_pipe(pipe_class_memory); 6866 %} 6867 6868 // Store Double 6869 instruct storeD(memory mem, regD src) %{ 6870 match(Set mem (StoreD mem src)); 6871 ins_cost(MEMORY_REF_COST); 6872 6873 format %{ "STFD $src, $mem" %} 6874 size(4); 6875 ins_encode( enc_stfd(src, mem) ); 6876 ins_pipe(pipe_class_memory); 6877 %} 6878 6879 //----------Store Instructions With Zeros-------------------------------------- 6880 6881 // Card-mark for CMS garbage collection. 6882 // This cardmark does an optimization so that it must not always 6883 // do a releasing store. For this, it gets the address of 6884 // CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6885 // (Using releaseFieldAddr in the match rule is a hack.) 6886 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6887 match(Set mem (StoreCM mem releaseFieldAddr)); 6888 effect(TEMP crx); 6889 predicate(false); 6890 ins_cost(MEMORY_REF_COST); 6891 6892 // See loadConP. 6893 ins_cannot_rematerialize(true); 6894 6895 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6896 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6897 ins_pipe(pipe_class_memory); 6898 %} 6899 6900 // Card-mark for CMS garbage collection. 6901 // This cardmark does an optimization so that it must not always 6902 // do a releasing store. For this, it needs the constant address of 6903 // CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6904 // This constant address is split off here by expand so we can use 6905 // adlc / matcher functionality to load it from the constant section. 6906 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6907 match(Set mem (StoreCM mem zero)); 6908 predicate(UseConcMarkSweepGC); 6909 6910 expand %{ 6911 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6912 iRegLdst releaseFieldAddress; 6913 flagsReg crx; 6914 loadConL_Ex(releaseFieldAddress, baseImm); 6915 storeCM_CMS(mem, releaseFieldAddress, crx); 6916 %} 6917 %} 6918 6919 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6920 match(Set mem (StoreCM mem zero)); 6921 predicate(UseG1GC); 6922 ins_cost(MEMORY_REF_COST); 6923 6924 ins_cannot_rematerialize(true); 6925 6926 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6927 size(8); 6928 ins_encode %{ 6929 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6930 __ li(R0, 0); 6931 //__ release(); // G1: oops are allowed to get visible after dirty marking 6932 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6933 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6934 %} 6935 ins_pipe(pipe_class_memory); 6936 %} 6937 6938 // Convert oop pointer into compressed form. 6939 6940 // Nodes for postalloc expand. 6941 6942 // Shift node for expand. 6943 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6944 // The match rule is needed to make it a 'MachTypeNode'! 6945 match(Set dst (EncodeP src)); 6946 predicate(false); 6947 6948 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6949 size(4); 6950 ins_encode %{ 6951 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6952 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 6953 %} 6954 ins_pipe(pipe_class_default); 6955 %} 6956 6957 // Add node for expand. 6958 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6959 // The match rule is needed to make it a 'MachTypeNode'! 6960 match(Set dst (EncodeP src)); 6961 predicate(false); 6962 6963 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6964 ins_encode %{ 6965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6966 __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 6967 %} 6968 ins_pipe(pipe_class_default); 6969 %} 6970 6971 // Conditional sub base. 6972 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6973 // The match rule is needed to make it a 'MachTypeNode'! 6974 match(Set dst (EncodeP (Binary crx src1))); 6975 predicate(false); 6976 6977 format %{ "BEQ $crx, done\n\t" 6978 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6979 "done:" %} 6980 ins_encode %{ 6981 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6982 Label done; 6983 __ beq($crx$$CondRegister, done); 6984 __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0); 6985 __ bind(done); 6986 %} 6987 ins_pipe(pipe_class_default); 6988 %} 6989 6990 // Power 7 can use isel instruction 6991 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6992 // The match rule is needed to make it a 'MachTypeNode'! 6993 match(Set dst (EncodeP (Binary crx src1))); 6994 predicate(false); 6995 6996 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6997 size(4); 6998 ins_encode %{ 6999 // This is a Power7 instruction for which no machine description exists. 7000 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7001 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7002 %} 7003 ins_pipe(pipe_class_default); 7004 %} 7005 7006 // Disjoint narrow oop base. 7007 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7008 match(Set dst (EncodeP src)); 7009 predicate(CompressedOops::base_disjoint()); 7010 7011 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7012 size(4); 7013 ins_encode %{ 7014 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7015 __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32); 7016 %} 7017 ins_pipe(pipe_class_default); 7018 %} 7019 7020 // shift != 0, base != 0 7021 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 7022 match(Set dst (EncodeP src)); 7023 effect(TEMP crx); 7024 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7025 CompressedOops::shift() != 0 && 7026 CompressedOops::base_overlaps()); 7027 7028 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7029 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7030 %} 7031 7032 // shift != 0, base != 0 7033 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7034 match(Set dst (EncodeP src)); 7035 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7036 CompressedOops::shift() != 0 && 7037 CompressedOops::base_overlaps()); 7038 7039 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7040 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7041 %} 7042 7043 // shift != 0, base == 0 7044 // TODO: This is the same as encodeP_shift. Merge! 7045 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7046 match(Set dst (EncodeP src)); 7047 predicate(CompressedOops::shift() != 0 && 7048 CompressedOops::base() ==0); 7049 7050 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7051 size(4); 7052 ins_encode %{ 7053 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7054 __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f); 7055 %} 7056 ins_pipe(pipe_class_default); 7057 %} 7058 7059 // Compressed OOPs with narrow_oop_shift == 0. 7060 // shift == 0, base == 0 7061 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7062 match(Set dst (EncodeP src)); 7063 predicate(CompressedOops::shift() == 0); 7064 7065 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7066 // variable size, 0 or 4. 7067 ins_encode %{ 7068 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7069 __ mr_if_needed($dst$$Register, $src$$Register); 7070 %} 7071 ins_pipe(pipe_class_default); 7072 %} 7073 7074 // Decode nodes. 7075 7076 // Shift node for expand. 7077 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7078 // The match rule is needed to make it a 'MachTypeNode'! 7079 match(Set dst (DecodeN src)); 7080 predicate(false); 7081 7082 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7083 size(4); 7084 ins_encode %{ 7085 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7086 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7087 %} 7088 ins_pipe(pipe_class_default); 7089 %} 7090 7091 // Add node for expand. 7092 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7093 // The match rule is needed to make it a 'MachTypeNode'! 7094 match(Set dst (DecodeN src)); 7095 predicate(false); 7096 7097 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7098 ins_encode %{ 7099 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7100 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7101 %} 7102 ins_pipe(pipe_class_default); 7103 %} 7104 7105 // conditianal add base for expand 7106 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7107 // The match rule is needed to make it a 'MachTypeNode'! 7108 // NOTICE that the rule is nonsense - we just have to make sure that: 7109 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7110 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7111 match(Set dst (DecodeN (Binary crx src))); 7112 predicate(false); 7113 7114 format %{ "BEQ $crx, done\n\t" 7115 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7116 "done:" %} 7117 ins_encode %{ 7118 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7119 Label done; 7120 __ beq($crx$$CondRegister, done); 7121 __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0); 7122 __ bind(done); 7123 %} 7124 ins_pipe(pipe_class_default); 7125 %} 7126 7127 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7128 // The match rule is needed to make it a 'MachTypeNode'! 7129 // NOTICE that the rule is nonsense - we just have to make sure that: 7130 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7131 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7132 match(Set dst (DecodeN (Binary crx src1))); 7133 predicate(false); 7134 7135 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7136 size(4); 7137 ins_encode %{ 7138 // This is a Power7 instruction for which no machine description exists. 7139 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7140 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7141 %} 7142 ins_pipe(pipe_class_default); 7143 %} 7144 7145 // shift != 0, base != 0 7146 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7147 match(Set dst (DecodeN src)); 7148 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7149 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7150 CompressedOops::shift() != 0 && 7151 CompressedOops::base() != 0); 7152 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7153 effect(TEMP crx); 7154 7155 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7156 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7157 %} 7158 7159 // shift != 0, base == 0 7160 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7161 match(Set dst (DecodeN src)); 7162 predicate(CompressedOops::shift() != 0 && 7163 CompressedOops::base() == 0); 7164 7165 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7166 size(4); 7167 ins_encode %{ 7168 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7169 __ sldi($dst$$Register, $src$$Register, CompressedOops::shift()); 7170 %} 7171 ins_pipe(pipe_class_default); 7172 %} 7173 7174 // Optimize DecodeN for disjoint base. 7175 // Shift narrow oop and or it into register that already contains the heap base. 7176 // Base == dst must hold, and is assured by construction in postaloc_expand. 7177 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7178 match(Set dst (DecodeN src)); 7179 effect(TEMP base); 7180 predicate(false); 7181 7182 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7183 size(4); 7184 ins_encode %{ 7185 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7186 __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift()); 7187 %} 7188 ins_pipe(pipe_class_default); 7189 %} 7190 7191 // Optimize DecodeN for disjoint base. 7192 // This node requires only one cycle on the critical path. 7193 // We must postalloc_expand as we can not express use_def effects where 7194 // the used register is L and the def'ed register P. 7195 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7196 match(Set dst (DecodeN src)); 7197 effect(TEMP_DEF dst); 7198 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7199 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7200 CompressedOops::base_disjoint()); 7201 ins_cost(DEFAULT_COST); 7202 7203 format %{ "MOV $dst, heapbase \t\n" 7204 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7205 postalloc_expand %{ 7206 loadBaseNode *n1 = new loadBaseNode(); 7207 n1->add_req(NULL); 7208 n1->_opnds[0] = op_dst; 7209 7210 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7211 n2->add_req(n_region, n_src, n1); 7212 n2->_opnds[0] = op_dst; 7213 n2->_opnds[1] = op_src; 7214 n2->_opnds[2] = op_dst; 7215 n2->_bottom_type = _bottom_type; 7216 7217 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7218 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7219 7220 nodes->push(n1); 7221 nodes->push(n2); 7222 %} 7223 %} 7224 7225 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7226 match(Set dst (DecodeN src)); 7227 effect(TEMP_DEF dst, TEMP crx); 7228 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7229 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7230 CompressedOops::base_disjoint() && VM_Version::has_isel()); 7231 ins_cost(3 * DEFAULT_COST); 7232 7233 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7234 postalloc_expand %{ 7235 loadBaseNode *n1 = new loadBaseNode(); 7236 n1->add_req(NULL); 7237 n1->_opnds[0] = op_dst; 7238 7239 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7240 n_compare->add_req(n_region, n_src); 7241 n_compare->_opnds[0] = op_crx; 7242 n_compare->_opnds[1] = op_src; 7243 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7244 7245 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7246 n2->add_req(n_region, n_src, n1); 7247 n2->_opnds[0] = op_dst; 7248 n2->_opnds[1] = op_src; 7249 n2->_opnds[2] = op_dst; 7250 n2->_bottom_type = _bottom_type; 7251 7252 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7253 n_cond_set->add_req(n_region, n_compare, n2); 7254 n_cond_set->_opnds[0] = op_dst; 7255 n_cond_set->_opnds[1] = op_crx; 7256 n_cond_set->_opnds[2] = op_dst; 7257 n_cond_set->_bottom_type = _bottom_type; 7258 7259 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7260 ra_->set_oop(n_cond_set, true); 7261 7262 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7263 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7264 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7265 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7266 7267 nodes->push(n1); 7268 nodes->push(n_compare); 7269 nodes->push(n2); 7270 nodes->push(n_cond_set); 7271 %} 7272 %} 7273 7274 // src != 0, shift != 0, base != 0 7275 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7276 match(Set dst (DecodeN src)); 7277 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7278 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7279 CompressedOops::shift() != 0 && 7280 CompressedOops::base() != 0); 7281 ins_cost(2 * DEFAULT_COST); 7282 7283 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7284 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7285 %} 7286 7287 // Compressed OOPs with narrow_oop_shift == 0. 7288 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7289 match(Set dst (DecodeN src)); 7290 predicate(CompressedOops::shift() == 0); 7291 ins_cost(DEFAULT_COST); 7292 7293 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7294 // variable size, 0 or 4. 7295 ins_encode %{ 7296 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7297 __ mr_if_needed($dst$$Register, $src$$Register); 7298 %} 7299 ins_pipe(pipe_class_default); 7300 %} 7301 7302 // Convert compressed oop into int for vectors alignment masking. 7303 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7304 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7305 predicate(CompressedOops::shift() == 0); 7306 ins_cost(DEFAULT_COST); 7307 7308 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7309 // variable size, 0 or 4. 7310 ins_encode %{ 7311 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7312 __ mr_if_needed($dst$$Register, $src$$Register); 7313 %} 7314 ins_pipe(pipe_class_default); 7315 %} 7316 7317 // Convert klass pointer into compressed form. 7318 7319 // Nodes for postalloc expand. 7320 7321 // Shift node for expand. 7322 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7323 // The match rule is needed to make it a 'MachTypeNode'! 7324 match(Set dst (EncodePKlass src)); 7325 predicate(false); 7326 7327 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7328 size(4); 7329 ins_encode %{ 7330 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7331 __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7332 %} 7333 ins_pipe(pipe_class_default); 7334 %} 7335 7336 // Add node for expand. 7337 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7338 // The match rule is needed to make it a 'MachTypeNode'! 7339 match(Set dst (EncodePKlass (Binary base src))); 7340 predicate(false); 7341 7342 format %{ "SUB $dst, $base, $src \t// encode" %} 7343 size(4); 7344 ins_encode %{ 7345 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7346 __ subf($dst$$Register, $base$$Register, $src$$Register); 7347 %} 7348 ins_pipe(pipe_class_default); 7349 %} 7350 7351 // Disjoint narrow oop base. 7352 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7353 match(Set dst (EncodePKlass src)); 7354 predicate(false /* TODO: PPC port CompressedKlassPointers::base_disjoint()*/); 7355 7356 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7357 size(4); 7358 ins_encode %{ 7359 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7360 __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32); 7361 %} 7362 ins_pipe(pipe_class_default); 7363 %} 7364 7365 // shift != 0, base != 0 7366 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7367 match(Set dst (EncodePKlass (Binary base src))); 7368 predicate(false); 7369 7370 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7371 postalloc_expand %{ 7372 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7373 n1->add_req(n_region, n_base, n_src); 7374 n1->_opnds[0] = op_dst; 7375 n1->_opnds[1] = op_base; 7376 n1->_opnds[2] = op_src; 7377 n1->_bottom_type = _bottom_type; 7378 7379 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7380 n2->add_req(n_region, n1); 7381 n2->_opnds[0] = op_dst; 7382 n2->_opnds[1] = op_dst; 7383 n2->_bottom_type = _bottom_type; 7384 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7385 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7386 7387 nodes->push(n1); 7388 nodes->push(n2); 7389 %} 7390 %} 7391 7392 // shift != 0, base != 0 7393 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7394 match(Set dst (EncodePKlass src)); 7395 //predicate(CompressedKlassPointers::shift() != 0 && 7396 // true /* TODO: PPC port CompressedKlassPointers::base_overlaps()*/); 7397 7398 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7399 ins_cost(DEFAULT_COST*2); // Don't count constant. 7400 expand %{ 7401 immL baseImm %{ (jlong)(intptr_t)CompressedKlassPointers::base() %} 7402 iRegLdst base; 7403 loadConL_Ex(base, baseImm); 7404 encodePKlass_not_null_Ex(dst, base, src); 7405 %} 7406 %} 7407 7408 // Decode nodes. 7409 7410 // Shift node for expand. 7411 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7412 // The match rule is needed to make it a 'MachTypeNode'! 7413 match(Set dst (DecodeNKlass src)); 7414 predicate(false); 7415 7416 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7417 size(4); 7418 ins_encode %{ 7419 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7420 __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift()); 7421 %} 7422 ins_pipe(pipe_class_default); 7423 %} 7424 7425 // Add node for expand. 7426 7427 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7428 // The match rule is needed to make it a 'MachTypeNode'! 7429 match(Set dst (DecodeNKlass (Binary base src))); 7430 predicate(false); 7431 7432 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7433 size(4); 7434 ins_encode %{ 7435 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7436 __ add($dst$$Register, $base$$Register, $src$$Register); 7437 %} 7438 ins_pipe(pipe_class_default); 7439 %} 7440 7441 // src != 0, shift != 0, base != 0 7442 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7443 match(Set dst (DecodeNKlass (Binary base src))); 7444 //effect(kill src); // We need a register for the immediate result after shifting. 7445 predicate(false); 7446 7447 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7448 postalloc_expand %{ 7449 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7450 n1->add_req(n_region, n_base, n_src); 7451 n1->_opnds[0] = op_dst; 7452 n1->_opnds[1] = op_base; 7453 n1->_opnds[2] = op_src; 7454 n1->_bottom_type = _bottom_type; 7455 7456 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7457 n2->add_req(n_region, n1); 7458 n2->_opnds[0] = op_dst; 7459 n2->_opnds[1] = op_dst; 7460 n2->_bottom_type = _bottom_type; 7461 7462 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7463 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7464 7465 nodes->push(n1); 7466 nodes->push(n2); 7467 %} 7468 %} 7469 7470 // src != 0, shift != 0, base != 0 7471 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7472 match(Set dst (DecodeNKlass src)); 7473 // predicate(CompressedKlassPointers::shift() != 0 && 7474 // CompressedKlassPointers::base() != 0); 7475 7476 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7477 7478 ins_cost(DEFAULT_COST*2); // Don't count constant. 7479 expand %{ 7480 // We add first, then we shift. Like this, we can get along with one register less. 7481 // But we have to load the base pre-shifted. 7482 immL baseImm %{ (jlong)((intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift()) %} 7483 iRegLdst base; 7484 loadConL_Ex(base, baseImm); 7485 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7486 %} 7487 %} 7488 7489 //----------MemBar Instructions----------------------------------------------- 7490 // Memory barrier flavors 7491 7492 instruct membar_acquire() %{ 7493 match(LoadFence); 7494 ins_cost(4*MEMORY_REF_COST); 7495 7496 format %{ "MEMBAR-acquire" %} 7497 size(4); 7498 ins_encode %{ 7499 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7500 __ acquire(); 7501 %} 7502 ins_pipe(pipe_class_default); 7503 %} 7504 7505 instruct unnecessary_membar_acquire() %{ 7506 match(MemBarAcquire); 7507 ins_cost(0); 7508 7509 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7510 size(0); 7511 ins_encode( /*empty*/ ); 7512 ins_pipe(pipe_class_default); 7513 %} 7514 7515 instruct membar_acquire_lock() %{ 7516 match(MemBarAcquireLock); 7517 ins_cost(0); 7518 7519 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7520 size(0); 7521 ins_encode( /*empty*/ ); 7522 ins_pipe(pipe_class_default); 7523 %} 7524 7525 instruct membar_release() %{ 7526 match(MemBarRelease); 7527 match(StoreFence); 7528 ins_cost(4*MEMORY_REF_COST); 7529 7530 format %{ "MEMBAR-release" %} 7531 size(4); 7532 ins_encode %{ 7533 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7534 __ release(); 7535 %} 7536 ins_pipe(pipe_class_default); 7537 %} 7538 7539 instruct membar_storestore() %{ 7540 match(MemBarStoreStore); 7541 ins_cost(4*MEMORY_REF_COST); 7542 7543 format %{ "MEMBAR-store-store" %} 7544 size(4); 7545 ins_encode %{ 7546 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7547 __ membar(Assembler::StoreStore); 7548 %} 7549 ins_pipe(pipe_class_default); 7550 %} 7551 7552 instruct membar_release_lock() %{ 7553 match(MemBarReleaseLock); 7554 ins_cost(0); 7555 7556 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7557 size(0); 7558 ins_encode( /*empty*/ ); 7559 ins_pipe(pipe_class_default); 7560 %} 7561 7562 instruct membar_volatile() %{ 7563 match(MemBarVolatile); 7564 ins_cost(4*MEMORY_REF_COST); 7565 7566 format %{ "MEMBAR-volatile" %} 7567 size(4); 7568 ins_encode %{ 7569 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7570 __ fence(); 7571 %} 7572 ins_pipe(pipe_class_default); 7573 %} 7574 7575 // This optimization is wrong on PPC. The following pattern is not supported: 7576 // MemBarVolatile 7577 // ^ ^ 7578 // | | 7579 // CtrlProj MemProj 7580 // ^ ^ 7581 // | | 7582 // | Load 7583 // | 7584 // MemBarVolatile 7585 // 7586 // The first MemBarVolatile could get optimized out! According to 7587 // Vladimir, this pattern can not occur on Oracle platforms. 7588 // However, it does occur on PPC64 (because of membars in 7589 // inline_unsafe_load_store). 7590 // 7591 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7592 // Don't forget to look at the implementation of post_store_load_barrier again, 7593 // we did other fixes in that method. 7594 //instruct unnecessary_membar_volatile() %{ 7595 // match(MemBarVolatile); 7596 // predicate(Matcher::post_store_load_barrier(n)); 7597 // ins_cost(0); 7598 // 7599 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7600 // size(0); 7601 // ins_encode( /*empty*/ ); 7602 // ins_pipe(pipe_class_default); 7603 //%} 7604 7605 instruct membar_CPUOrder() %{ 7606 match(MemBarCPUOrder); 7607 ins_cost(0); 7608 7609 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7610 size(0); 7611 ins_encode( /*empty*/ ); 7612 ins_pipe(pipe_class_default); 7613 %} 7614 7615 //----------Conditional Move--------------------------------------------------- 7616 7617 // Cmove using isel. 7618 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7619 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7620 predicate(VM_Version::has_isel()); 7621 ins_cost(DEFAULT_COST); 7622 7623 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7624 size(4); 7625 ins_encode %{ 7626 // This is a Power7 instruction for which no machine description 7627 // exists. Anyways, the scheduler should be off on Power7. 7628 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7629 int cc = $cmp$$cmpcode; 7630 __ isel($dst$$Register, $crx$$CondRegister, 7631 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7632 %} 7633 ins_pipe(pipe_class_default); 7634 %} 7635 7636 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7637 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7638 predicate(!VM_Version::has_isel()); 7639 ins_cost(DEFAULT_COST+BRANCH_COST); 7640 7641 ins_variable_size_depending_on_alignment(true); 7642 7643 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7644 // Worst case is branch + move + stop, no stop without scheduler 7645 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7646 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7647 ins_pipe(pipe_class_default); 7648 %} 7649 7650 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7651 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7652 ins_cost(DEFAULT_COST+BRANCH_COST); 7653 7654 ins_variable_size_depending_on_alignment(true); 7655 7656 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7657 // Worst case is branch + move + stop, no stop without scheduler 7658 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7659 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7660 ins_pipe(pipe_class_default); 7661 %} 7662 7663 // Cmove using isel. 7664 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7665 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7666 predicate(VM_Version::has_isel()); 7667 ins_cost(DEFAULT_COST); 7668 7669 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7670 size(4); 7671 ins_encode %{ 7672 // This is a Power7 instruction for which no machine description 7673 // exists. Anyways, the scheduler should be off on Power7. 7674 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7675 int cc = $cmp$$cmpcode; 7676 __ isel($dst$$Register, $crx$$CondRegister, 7677 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7678 %} 7679 ins_pipe(pipe_class_default); 7680 %} 7681 7682 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7683 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7684 predicate(!VM_Version::has_isel()); 7685 ins_cost(DEFAULT_COST+BRANCH_COST); 7686 7687 ins_variable_size_depending_on_alignment(true); 7688 7689 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7690 // Worst case is branch + move + stop, no stop without scheduler. 7691 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7692 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7693 ins_pipe(pipe_class_default); 7694 %} 7695 7696 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7697 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7698 ins_cost(DEFAULT_COST+BRANCH_COST); 7699 7700 ins_variable_size_depending_on_alignment(true); 7701 7702 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7703 // Worst case is branch + move + stop, no stop without scheduler. 7704 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7705 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7706 ins_pipe(pipe_class_default); 7707 %} 7708 7709 // Cmove using isel. 7710 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7711 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7712 predicate(VM_Version::has_isel()); 7713 ins_cost(DEFAULT_COST); 7714 7715 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7716 size(4); 7717 ins_encode %{ 7718 // This is a Power7 instruction for which no machine description 7719 // exists. Anyways, the scheduler should be off on Power7. 7720 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7721 int cc = $cmp$$cmpcode; 7722 __ isel($dst$$Register, $crx$$CondRegister, 7723 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7724 %} 7725 ins_pipe(pipe_class_default); 7726 %} 7727 7728 // Conditional move for RegN. Only cmov(reg, reg). 7729 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7730 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7731 predicate(!VM_Version::has_isel()); 7732 ins_cost(DEFAULT_COST+BRANCH_COST); 7733 7734 ins_variable_size_depending_on_alignment(true); 7735 7736 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7737 // Worst case is branch + move + stop, no stop without scheduler. 7738 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7739 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7740 ins_pipe(pipe_class_default); 7741 %} 7742 7743 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7744 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7745 ins_cost(DEFAULT_COST+BRANCH_COST); 7746 7747 ins_variable_size_depending_on_alignment(true); 7748 7749 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7750 // Worst case is branch + move + stop, no stop without scheduler. 7751 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7752 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7753 ins_pipe(pipe_class_default); 7754 %} 7755 7756 // Cmove using isel. 7757 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7758 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7759 predicate(VM_Version::has_isel()); 7760 ins_cost(DEFAULT_COST); 7761 7762 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7763 size(4); 7764 ins_encode %{ 7765 // This is a Power7 instruction for which no machine description 7766 // exists. Anyways, the scheduler should be off on Power7. 7767 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7768 int cc = $cmp$$cmpcode; 7769 __ isel($dst$$Register, $crx$$CondRegister, 7770 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7771 %} 7772 ins_pipe(pipe_class_default); 7773 %} 7774 7775 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7776 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7777 predicate(!VM_Version::has_isel()); 7778 ins_cost(DEFAULT_COST+BRANCH_COST); 7779 7780 ins_variable_size_depending_on_alignment(true); 7781 7782 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7783 // Worst case is branch + move + stop, no stop without scheduler. 7784 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7785 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7790 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7791 ins_cost(DEFAULT_COST+BRANCH_COST); 7792 7793 ins_variable_size_depending_on_alignment(true); 7794 7795 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7796 // Worst case is branch + move + stop, no stop without scheduler. 7797 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 7798 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7799 ins_pipe(pipe_class_default); 7800 %} 7801 7802 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7803 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7804 ins_cost(DEFAULT_COST+BRANCH_COST); 7805 7806 ins_variable_size_depending_on_alignment(true); 7807 7808 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7809 // Worst case is branch + move + stop, no stop without scheduler. 7810 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7811 ins_encode %{ 7812 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7813 Label done; 7814 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7815 // Branch if not (cmp crx). 7816 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7817 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7818 // TODO PPC port __ endgroup_if_needed(_size == 12); 7819 __ bind(done); 7820 %} 7821 ins_pipe(pipe_class_default); 7822 %} 7823 7824 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7825 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7826 ins_cost(DEFAULT_COST+BRANCH_COST); 7827 7828 ins_variable_size_depending_on_alignment(true); 7829 7830 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7831 // Worst case is branch + move + stop, no stop without scheduler. 7832 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 7833 ins_encode %{ 7834 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7835 Label done; 7836 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7837 // Branch if not (cmp crx). 7838 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7839 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7840 // TODO PPC port __ endgroup_if_needed(_size == 12); 7841 __ bind(done); 7842 %} 7843 ins_pipe(pipe_class_default); 7844 %} 7845 7846 //----------Conditional_store-------------------------------------------------- 7847 // Conditional-store of the updated heap-top. 7848 // Used during allocation of the shared heap. 7849 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7850 7851 // As compareAndSwapL, but return flag register instead of boolean value in 7852 // int register. 7853 // Used by sun/misc/AtomicLongCSImpl.java. 7854 // Mem_ptr must be a memory operand, else this node does not get 7855 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7856 // can be rematerialized which leads to errors. 7857 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7858 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7859 effect(TEMP cr0); 7860 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7861 ins_encode %{ 7862 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7863 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7864 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7865 noreg, NULL, true); 7866 %} 7867 ins_pipe(pipe_class_default); 7868 %} 7869 7870 // As compareAndSwapP, but return flag register instead of boolean value in 7871 // int register. 7872 // This instruction is matched if UseTLAB is off. 7873 // Mem_ptr must be a memory operand, else this node does not get 7874 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7875 // can be rematerialized which leads to errors. 7876 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7877 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7878 ins_cost(2*MEMORY_REF_COST); 7879 7880 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7881 ins_encode %{ 7882 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7883 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7884 %} 7885 ins_pipe(pipe_class_memory); 7886 %} 7887 7888 // Implement LoadPLocked. Must be ordered against changes of the memory location 7889 // by storePConditional. 7890 // Don't know whether this is ever used. 7891 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7892 match(Set dst (LoadPLocked mem)); 7893 ins_cost(2*MEMORY_REF_COST); 7894 7895 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7896 size(4); 7897 ins_encode %{ 7898 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7899 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7900 %} 7901 ins_pipe(pipe_class_memory); 7902 %} 7903 7904 //----------Compare-And-Swap--------------------------------------------------- 7905 7906 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7907 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7908 // matched. 7909 7910 // Strong versions: 7911 7912 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7913 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7914 predicate(VM_Version::has_lqarx()); 7915 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7916 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7917 ins_encode %{ 7918 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7919 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7920 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7921 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7922 $res$$Register, true); 7923 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7924 __ isync(); 7925 } else { 7926 __ sync(); 7927 } 7928 %} 7929 ins_pipe(pipe_class_default); 7930 %} 7931 7932 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7933 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7934 predicate(!VM_Version::has_lqarx()); 7935 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7936 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7937 ins_encode %{ 7938 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7939 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7940 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7941 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7942 $res$$Register, true); 7943 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7944 __ isync(); 7945 } else { 7946 __ sync(); 7947 } 7948 %} 7949 ins_pipe(pipe_class_default); 7950 %} 7951 7952 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7953 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7954 predicate(VM_Version::has_lqarx()); 7955 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7956 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7957 ins_encode %{ 7958 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7959 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7960 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7961 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7962 $res$$Register, true); 7963 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7964 __ isync(); 7965 } else { 7966 __ sync(); 7967 } 7968 %} 7969 ins_pipe(pipe_class_default); 7970 %} 7971 7972 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7973 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7974 predicate(!VM_Version::has_lqarx()); 7975 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7976 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7977 ins_encode %{ 7978 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7979 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7980 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7981 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7982 $res$$Register, true); 7983 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7984 __ isync(); 7985 } else { 7986 __ sync(); 7987 } 7988 %} 7989 ins_pipe(pipe_class_default); 7990 %} 7991 7992 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7993 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7994 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7995 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7996 ins_encode %{ 7997 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7998 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7999 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8000 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8001 $res$$Register, true); 8002 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8003 __ isync(); 8004 } else { 8005 __ sync(); 8006 } 8007 %} 8008 ins_pipe(pipe_class_default); 8009 %} 8010 8011 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8012 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 8013 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8014 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8015 ins_encode %{ 8016 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8017 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8018 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8019 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8020 $res$$Register, true); 8021 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8022 __ isync(); 8023 } else { 8024 __ sync(); 8025 } 8026 %} 8027 ins_pipe(pipe_class_default); 8028 %} 8029 8030 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8031 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8032 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8033 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8034 ins_encode %{ 8035 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8036 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8037 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8038 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8039 $res$$Register, NULL, true); 8040 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8041 __ isync(); 8042 } else { 8043 __ sync(); 8044 } 8045 %} 8046 ins_pipe(pipe_class_default); 8047 %} 8048 8049 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8050 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8051 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8052 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8053 ins_encode %{ 8054 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8056 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8057 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8058 $res$$Register, NULL, true); 8059 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8060 __ isync(); 8061 } else { 8062 __ sync(); 8063 } 8064 %} 8065 ins_pipe(pipe_class_default); 8066 %} 8067 8068 // Weak versions: 8069 8070 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8071 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8072 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8073 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8074 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8075 ins_encode %{ 8076 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8077 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8078 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8079 MacroAssembler::MemBarNone, 8080 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8081 %} 8082 ins_pipe(pipe_class_default); 8083 %} 8084 8085 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8086 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8087 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8088 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8089 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8090 ins_encode %{ 8091 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8092 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8093 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8094 MacroAssembler::MemBarNone, 8095 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8096 %} 8097 ins_pipe(pipe_class_default); 8098 %} 8099 8100 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8101 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8102 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8103 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8104 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8105 ins_encode %{ 8106 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8107 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8108 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8109 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8110 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8111 %} 8112 ins_pipe(pipe_class_default); 8113 %} 8114 8115 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8116 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8117 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8118 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8119 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8120 ins_encode %{ 8121 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8122 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8123 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8124 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8125 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8126 %} 8127 ins_pipe(pipe_class_default); 8128 %} 8129 8130 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8131 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8132 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8133 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8134 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8135 ins_encode %{ 8136 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8137 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8138 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8139 MacroAssembler::MemBarNone, 8140 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8141 %} 8142 ins_pipe(pipe_class_default); 8143 %} 8144 8145 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8146 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8147 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8148 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8149 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8150 ins_encode %{ 8151 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8152 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8153 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8154 MacroAssembler::MemBarNone, 8155 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8156 %} 8157 ins_pipe(pipe_class_default); 8158 %} 8159 8160 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8161 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8162 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8163 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8164 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8165 ins_encode %{ 8166 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8167 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8168 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8169 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8170 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8171 %} 8172 ins_pipe(pipe_class_default); 8173 %} 8174 8175 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8176 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8177 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8178 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8179 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8180 ins_encode %{ 8181 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8182 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8183 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8184 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8185 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8186 %} 8187 ins_pipe(pipe_class_default); 8188 %} 8189 8190 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8191 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8192 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8193 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8194 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8195 ins_encode %{ 8196 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8197 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8198 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8199 MacroAssembler::MemBarNone, 8200 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8201 %} 8202 ins_pipe(pipe_class_default); 8203 %} 8204 8205 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8206 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8207 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8208 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8209 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8210 ins_encode %{ 8211 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8212 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8213 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8214 // value is never passed to caller. 8215 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8216 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8217 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8218 %} 8219 ins_pipe(pipe_class_default); 8220 %} 8221 8222 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8223 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8224 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8225 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8226 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8227 ins_encode %{ 8228 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8229 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8230 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8231 MacroAssembler::MemBarNone, 8232 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8233 %} 8234 ins_pipe(pipe_class_default); 8235 %} 8236 8237 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8238 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8239 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8240 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8241 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8242 ins_encode %{ 8243 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8244 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8245 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8246 // value is never passed to caller. 8247 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8248 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8249 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8250 %} 8251 ins_pipe(pipe_class_default); 8252 %} 8253 8254 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8255 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8256 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8257 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8258 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8259 ins_encode %{ 8260 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8261 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8262 // value is never passed to caller. 8263 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8264 MacroAssembler::MemBarNone, 8265 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8266 %} 8267 ins_pipe(pipe_class_default); 8268 %} 8269 8270 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8271 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8272 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8273 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8274 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8275 ins_encode %{ 8276 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8277 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8278 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8279 // value is never passed to caller. 8280 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8281 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8282 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8283 %} 8284 ins_pipe(pipe_class_default); 8285 %} 8286 8287 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8288 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8289 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8290 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8291 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8292 ins_encode %{ 8293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8294 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8295 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8296 MacroAssembler::MemBarNone, 8297 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8298 %} 8299 ins_pipe(pipe_class_default); 8300 %} 8301 8302 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8303 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8304 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8305 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8306 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8307 ins_encode %{ 8308 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8309 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8310 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8311 // value is never passed to caller. 8312 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8313 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8314 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8315 %} 8316 ins_pipe(pipe_class_default); 8317 %} 8318 8319 // CompareAndExchange 8320 8321 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8322 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8323 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8324 effect(TEMP_DEF res, TEMP cr0); 8325 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8326 ins_encode %{ 8327 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8328 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8329 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8330 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8331 noreg, true); 8332 %} 8333 ins_pipe(pipe_class_default); 8334 %} 8335 8336 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8337 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8338 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8339 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8340 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8341 ins_encode %{ 8342 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8343 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8344 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8345 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8346 noreg, true); 8347 %} 8348 ins_pipe(pipe_class_default); 8349 %} 8350 8351 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8352 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8353 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8354 effect(TEMP_DEF res, TEMP cr0); 8355 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8356 ins_encode %{ 8357 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8358 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8359 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8360 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8361 noreg, true); 8362 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8363 __ isync(); 8364 } else { 8365 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8366 __ sync(); 8367 } 8368 %} 8369 ins_pipe(pipe_class_default); 8370 %} 8371 8372 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8373 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8374 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8375 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8376 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8377 ins_encode %{ 8378 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8379 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8380 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8381 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8382 noreg, true); 8383 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8384 __ isync(); 8385 } else { 8386 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8387 __ sync(); 8388 } 8389 %} 8390 ins_pipe(pipe_class_default); 8391 %} 8392 8393 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8394 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8395 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8396 effect(TEMP_DEF res, TEMP cr0); 8397 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8398 ins_encode %{ 8399 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8400 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8401 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8402 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8403 noreg, true); 8404 %} 8405 ins_pipe(pipe_class_default); 8406 %} 8407 8408 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8409 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8410 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8411 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8412 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8413 ins_encode %{ 8414 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8415 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8416 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8417 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8418 noreg, true); 8419 %} 8420 ins_pipe(pipe_class_default); 8421 %} 8422 8423 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8424 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8425 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8426 effect(TEMP_DEF res, TEMP cr0); 8427 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8428 ins_encode %{ 8429 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8430 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8431 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8432 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8433 noreg, true); 8434 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8435 __ isync(); 8436 } else { 8437 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8438 __ sync(); 8439 } 8440 %} 8441 ins_pipe(pipe_class_default); 8442 %} 8443 8444 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8445 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8446 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8447 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8448 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8449 ins_encode %{ 8450 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8451 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8452 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8453 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8454 noreg, true); 8455 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8456 __ isync(); 8457 } else { 8458 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8459 __ sync(); 8460 } 8461 %} 8462 ins_pipe(pipe_class_default); 8463 %} 8464 8465 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8466 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8467 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8468 effect(TEMP_DEF res, TEMP cr0); 8469 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8470 ins_encode %{ 8471 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8472 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8473 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8474 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8475 noreg, true); 8476 %} 8477 ins_pipe(pipe_class_default); 8478 %} 8479 8480 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8481 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8482 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8483 effect(TEMP_DEF res, TEMP cr0); 8484 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8485 ins_encode %{ 8486 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8487 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8488 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8489 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8490 noreg, true); 8491 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8492 __ isync(); 8493 } else { 8494 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8495 __ sync(); 8496 } 8497 %} 8498 ins_pipe(pipe_class_default); 8499 %} 8500 8501 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8502 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8503 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8504 effect(TEMP_DEF res, TEMP cr0); 8505 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8506 ins_encode %{ 8507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8508 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8509 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8510 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8511 noreg, true); 8512 %} 8513 ins_pipe(pipe_class_default); 8514 %} 8515 8516 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8517 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8518 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8519 effect(TEMP_DEF res, TEMP cr0); 8520 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8521 ins_encode %{ 8522 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8523 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8524 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8525 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8526 noreg, true); 8527 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8528 __ isync(); 8529 } else { 8530 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8531 __ sync(); 8532 } 8533 %} 8534 ins_pipe(pipe_class_default); 8535 %} 8536 8537 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8538 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8539 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8540 effect(TEMP_DEF res, TEMP cr0); 8541 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8542 ins_encode %{ 8543 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8544 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8545 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8546 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8547 noreg, NULL, true); 8548 %} 8549 ins_pipe(pipe_class_default); 8550 %} 8551 8552 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8553 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8554 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8555 effect(TEMP_DEF res, TEMP cr0); 8556 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8557 ins_encode %{ 8558 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8559 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8560 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8561 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8562 noreg, NULL, true); 8563 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8564 __ isync(); 8565 } else { 8566 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8567 __ sync(); 8568 } 8569 %} 8570 ins_pipe(pipe_class_default); 8571 %} 8572 8573 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8574 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8575 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8576 effect(TEMP_DEF res, TEMP cr0); 8577 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8578 ins_encode %{ 8579 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8580 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8581 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8582 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8583 noreg, NULL, true); 8584 %} 8585 ins_pipe(pipe_class_default); 8586 %} 8587 8588 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8589 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8590 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8591 effect(TEMP_DEF res, TEMP cr0); 8592 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8593 ins_encode %{ 8594 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8595 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8596 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8597 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8598 noreg, NULL, true); 8599 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8600 __ isync(); 8601 } else { 8602 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8603 __ sync(); 8604 } 8605 %} 8606 ins_pipe(pipe_class_default); 8607 %} 8608 8609 // Special RMW 8610 8611 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8612 match(Set res (GetAndAddB mem_ptr src)); 8613 predicate(VM_Version::has_lqarx()); 8614 effect(TEMP_DEF res, TEMP cr0); 8615 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8616 ins_encode %{ 8617 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8618 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8619 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8620 __ isync(); 8621 } else { 8622 __ sync(); 8623 } 8624 %} 8625 ins_pipe(pipe_class_default); 8626 %} 8627 8628 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8629 match(Set res (GetAndAddB mem_ptr src)); 8630 predicate(!VM_Version::has_lqarx()); 8631 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8632 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8633 ins_encode %{ 8634 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8635 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8636 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8637 __ isync(); 8638 } else { 8639 __ sync(); 8640 } 8641 %} 8642 ins_pipe(pipe_class_default); 8643 %} 8644 8645 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8646 match(Set res (GetAndAddS mem_ptr src)); 8647 predicate(VM_Version::has_lqarx()); 8648 effect(TEMP_DEF res, TEMP cr0); 8649 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8650 ins_encode %{ 8651 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8652 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8653 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8654 __ isync(); 8655 } else { 8656 __ sync(); 8657 } 8658 %} 8659 ins_pipe(pipe_class_default); 8660 %} 8661 8662 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8663 match(Set res (GetAndAddS mem_ptr src)); 8664 predicate(!VM_Version::has_lqarx()); 8665 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8666 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8667 ins_encode %{ 8668 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8669 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8670 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8671 __ isync(); 8672 } else { 8673 __ sync(); 8674 } 8675 %} 8676 ins_pipe(pipe_class_default); 8677 %} 8678 8679 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8680 match(Set res (GetAndAddI mem_ptr src)); 8681 effect(TEMP_DEF res, TEMP cr0); 8682 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8683 ins_encode %{ 8684 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8685 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8686 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8687 __ isync(); 8688 } else { 8689 __ sync(); 8690 } 8691 %} 8692 ins_pipe(pipe_class_default); 8693 %} 8694 8695 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8696 match(Set res (GetAndAddL mem_ptr src)); 8697 effect(TEMP_DEF res, TEMP cr0); 8698 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8699 ins_encode %{ 8700 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8701 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8702 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8703 __ isync(); 8704 } else { 8705 __ sync(); 8706 } 8707 %} 8708 ins_pipe(pipe_class_default); 8709 %} 8710 8711 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8712 match(Set res (GetAndSetB mem_ptr src)); 8713 predicate(VM_Version::has_lqarx()); 8714 effect(TEMP_DEF res, TEMP cr0); 8715 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8716 ins_encode %{ 8717 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8718 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8719 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8720 __ isync(); 8721 } else { 8722 __ sync(); 8723 } 8724 %} 8725 ins_pipe(pipe_class_default); 8726 %} 8727 8728 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8729 match(Set res (GetAndSetB mem_ptr src)); 8730 predicate(!VM_Version::has_lqarx()); 8731 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8732 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8733 ins_encode %{ 8734 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8735 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8736 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8737 __ isync(); 8738 } else { 8739 __ sync(); 8740 } 8741 %} 8742 ins_pipe(pipe_class_default); 8743 %} 8744 8745 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8746 match(Set res (GetAndSetS mem_ptr src)); 8747 predicate(VM_Version::has_lqarx()); 8748 effect(TEMP_DEF res, TEMP cr0); 8749 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8750 ins_encode %{ 8751 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8752 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8753 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8754 __ isync(); 8755 } else { 8756 __ sync(); 8757 } 8758 %} 8759 ins_pipe(pipe_class_default); 8760 %} 8761 8762 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8763 match(Set res (GetAndSetS mem_ptr src)); 8764 predicate(!VM_Version::has_lqarx()); 8765 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8766 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8767 ins_encode %{ 8768 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8769 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8770 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8771 __ isync(); 8772 } else { 8773 __ sync(); 8774 } 8775 %} 8776 ins_pipe(pipe_class_default); 8777 %} 8778 8779 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8780 match(Set res (GetAndSetI mem_ptr src)); 8781 effect(TEMP_DEF res, TEMP cr0); 8782 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8783 ins_encode %{ 8784 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8785 MacroAssembler::cmpxchgx_hint_atomic_update()); 8786 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8787 __ isync(); 8788 } else { 8789 __ sync(); 8790 } 8791 %} 8792 ins_pipe(pipe_class_default); 8793 %} 8794 8795 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8796 match(Set res (GetAndSetL mem_ptr src)); 8797 effect(TEMP_DEF res, TEMP cr0); 8798 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8799 ins_encode %{ 8800 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8801 MacroAssembler::cmpxchgx_hint_atomic_update()); 8802 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8803 __ isync(); 8804 } else { 8805 __ sync(); 8806 } 8807 %} 8808 ins_pipe(pipe_class_default); 8809 %} 8810 8811 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8812 match(Set res (GetAndSetP mem_ptr src)); 8813 effect(TEMP_DEF res, TEMP cr0); 8814 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8815 ins_encode %{ 8816 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8817 MacroAssembler::cmpxchgx_hint_atomic_update()); 8818 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8819 __ isync(); 8820 } else { 8821 __ sync(); 8822 } 8823 %} 8824 ins_pipe(pipe_class_default); 8825 %} 8826 8827 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8828 match(Set res (GetAndSetN mem_ptr src)); 8829 effect(TEMP_DEF res, TEMP cr0); 8830 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8831 ins_encode %{ 8832 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8833 MacroAssembler::cmpxchgx_hint_atomic_update()); 8834 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8835 __ isync(); 8836 } else { 8837 __ sync(); 8838 } 8839 %} 8840 ins_pipe(pipe_class_default); 8841 %} 8842 8843 //----------Arithmetic Instructions-------------------------------------------- 8844 // Addition Instructions 8845 8846 // Register Addition 8847 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8848 match(Set dst (AddI src1 src2)); 8849 format %{ "ADD $dst, $src1, $src2" %} 8850 size(4); 8851 ins_encode %{ 8852 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8853 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8854 %} 8855 ins_pipe(pipe_class_default); 8856 %} 8857 8858 // Expand does not work with above instruct. (??) 8859 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8860 // no match-rule 8861 effect(DEF dst, USE src1, USE src2); 8862 format %{ "ADD $dst, $src1, $src2" %} 8863 size(4); 8864 ins_encode %{ 8865 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8866 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8867 %} 8868 ins_pipe(pipe_class_default); 8869 %} 8870 8871 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8872 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8873 ins_cost(DEFAULT_COST*3); 8874 8875 expand %{ 8876 // FIXME: we should do this in the ideal world. 8877 iRegIdst tmp1; 8878 iRegIdst tmp2; 8879 addI_reg_reg(tmp1, src1, src2); 8880 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8881 addI_reg_reg(dst, tmp1, tmp2); 8882 %} 8883 %} 8884 8885 // Immediate Addition 8886 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8887 match(Set dst (AddI src1 src2)); 8888 format %{ "ADDI $dst, $src1, $src2" %} 8889 size(4); 8890 ins_encode %{ 8891 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8892 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8893 %} 8894 ins_pipe(pipe_class_default); 8895 %} 8896 8897 // Immediate Addition with 16-bit shifted operand 8898 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8899 match(Set dst (AddI src1 src2)); 8900 format %{ "ADDIS $dst, $src1, $src2" %} 8901 size(4); 8902 ins_encode %{ 8903 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8904 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8905 %} 8906 ins_pipe(pipe_class_default); 8907 %} 8908 8909 // Long Addition 8910 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8911 match(Set dst (AddL src1 src2)); 8912 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8913 size(4); 8914 ins_encode %{ 8915 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8916 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8917 %} 8918 ins_pipe(pipe_class_default); 8919 %} 8920 8921 // Expand does not work with above instruct. (??) 8922 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8923 // no match-rule 8924 effect(DEF dst, USE src1, USE src2); 8925 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8926 size(4); 8927 ins_encode %{ 8928 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8929 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8930 %} 8931 ins_pipe(pipe_class_default); 8932 %} 8933 8934 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8935 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8936 ins_cost(DEFAULT_COST*3); 8937 8938 expand %{ 8939 // FIXME: we should do this in the ideal world. 8940 iRegLdst tmp1; 8941 iRegLdst tmp2; 8942 addL_reg_reg(tmp1, src1, src2); 8943 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8944 addL_reg_reg(dst, tmp1, tmp2); 8945 %} 8946 %} 8947 8948 // AddL + ConvL2I. 8949 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8950 match(Set dst (ConvL2I (AddL src1 src2))); 8951 8952 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8953 size(4); 8954 ins_encode %{ 8955 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8956 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8957 %} 8958 ins_pipe(pipe_class_default); 8959 %} 8960 8961 // No constant pool entries required. 8962 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8963 match(Set dst (AddL src1 src2)); 8964 8965 format %{ "ADDI $dst, $src1, $src2" %} 8966 size(4); 8967 ins_encode %{ 8968 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8969 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8970 %} 8971 ins_pipe(pipe_class_default); 8972 %} 8973 8974 // Long Immediate Addition with 16-bit shifted operand. 8975 // No constant pool entries required. 8976 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8977 match(Set dst (AddL src1 src2)); 8978 8979 format %{ "ADDIS $dst, $src1, $src2" %} 8980 size(4); 8981 ins_encode %{ 8982 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8983 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8984 %} 8985 ins_pipe(pipe_class_default); 8986 %} 8987 8988 // Pointer Register Addition 8989 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8990 match(Set dst (AddP src1 src2)); 8991 format %{ "ADD $dst, $src1, $src2" %} 8992 size(4); 8993 ins_encode %{ 8994 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8995 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8996 %} 8997 ins_pipe(pipe_class_default); 8998 %} 8999 9000 // Pointer Immediate Addition 9001 // No constant pool entries required. 9002 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 9003 match(Set dst (AddP src1 src2)); 9004 9005 format %{ "ADDI $dst, $src1, $src2" %} 9006 size(4); 9007 ins_encode %{ 9008 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 9009 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 9010 %} 9011 ins_pipe(pipe_class_default); 9012 %} 9013 9014 // Pointer Immediate Addition with 16-bit shifted operand. 9015 // No constant pool entries required. 9016 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 9017 match(Set dst (AddP src1 src2)); 9018 9019 format %{ "ADDIS $dst, $src1, $src2" %} 9020 size(4); 9021 ins_encode %{ 9022 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9023 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9024 %} 9025 ins_pipe(pipe_class_default); 9026 %} 9027 9028 //--------------------- 9029 // Subtraction Instructions 9030 9031 // Register Subtraction 9032 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9033 match(Set dst (SubI src1 src2)); 9034 format %{ "SUBF $dst, $src2, $src1" %} 9035 size(4); 9036 ins_encode %{ 9037 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9038 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9039 %} 9040 ins_pipe(pipe_class_default); 9041 %} 9042 9043 // Immediate Subtraction 9044 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9045 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9046 9047 // SubI from constant (using subfic). 9048 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9049 match(Set dst (SubI src1 src2)); 9050 format %{ "SUBI $dst, $src1, $src2" %} 9051 9052 size(4); 9053 ins_encode %{ 9054 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9055 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9056 %} 9057 ins_pipe(pipe_class_default); 9058 %} 9059 9060 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9061 // positive integers and 0xF...F for negative ones. 9062 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9063 // no match-rule, false predicate 9064 effect(DEF dst, USE src); 9065 predicate(false); 9066 9067 format %{ "SRAWI $dst, $src, #31" %} 9068 size(4); 9069 ins_encode %{ 9070 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9071 __ srawi($dst$$Register, $src$$Register, 0x1f); 9072 %} 9073 ins_pipe(pipe_class_default); 9074 %} 9075 9076 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9077 match(Set dst (AbsI src)); 9078 ins_cost(DEFAULT_COST*3); 9079 9080 expand %{ 9081 iRegIdst tmp1; 9082 iRegIdst tmp2; 9083 signmask32I_regI(tmp1, src); 9084 xorI_reg_reg(tmp2, tmp1, src); 9085 subI_reg_reg(dst, tmp2, tmp1); 9086 %} 9087 %} 9088 9089 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9090 match(Set dst (SubI zero src2)); 9091 format %{ "NEG $dst, $src2" %} 9092 size(4); 9093 ins_encode %{ 9094 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9095 __ neg($dst$$Register, $src2$$Register); 9096 %} 9097 ins_pipe(pipe_class_default); 9098 %} 9099 9100 // Long subtraction 9101 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9102 match(Set dst (SubL src1 src2)); 9103 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9104 size(4); 9105 ins_encode %{ 9106 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9107 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9108 %} 9109 ins_pipe(pipe_class_default); 9110 %} 9111 9112 // SubL + convL2I. 9113 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9114 match(Set dst (ConvL2I (SubL src1 src2))); 9115 9116 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9117 size(4); 9118 ins_encode %{ 9119 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9120 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9121 %} 9122 ins_pipe(pipe_class_default); 9123 %} 9124 9125 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9126 // positive longs and 0xF...F for negative ones. 9127 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9128 // no match-rule, false predicate 9129 effect(DEF dst, USE src); 9130 predicate(false); 9131 9132 format %{ "SRADI $dst, $src, #63" %} 9133 size(4); 9134 ins_encode %{ 9135 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9136 __ sradi($dst$$Register, $src$$Register, 0x3f); 9137 %} 9138 ins_pipe(pipe_class_default); 9139 %} 9140 9141 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9142 // positive longs and 0xF...F for negative ones. 9143 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9144 // no match-rule, false predicate 9145 effect(DEF dst, USE src); 9146 predicate(false); 9147 9148 format %{ "SRADI $dst, $src, #63" %} 9149 size(4); 9150 ins_encode %{ 9151 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9152 __ sradi($dst$$Register, $src$$Register, 0x3f); 9153 %} 9154 ins_pipe(pipe_class_default); 9155 %} 9156 9157 // Long negation 9158 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9159 match(Set dst (SubL zero src2)); 9160 format %{ "NEG $dst, $src2 \t// long" %} 9161 size(4); 9162 ins_encode %{ 9163 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9164 __ neg($dst$$Register, $src2$$Register); 9165 %} 9166 ins_pipe(pipe_class_default); 9167 %} 9168 9169 // NegL + ConvL2I. 9170 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9171 match(Set dst (ConvL2I (SubL zero src2))); 9172 9173 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9174 size(4); 9175 ins_encode %{ 9176 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9177 __ neg($dst$$Register, $src2$$Register); 9178 %} 9179 ins_pipe(pipe_class_default); 9180 %} 9181 9182 // Multiplication Instructions 9183 // Integer Multiplication 9184 9185 // Register Multiplication 9186 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9187 match(Set dst (MulI src1 src2)); 9188 ins_cost(DEFAULT_COST); 9189 9190 format %{ "MULLW $dst, $src1, $src2" %} 9191 size(4); 9192 ins_encode %{ 9193 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9194 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9195 %} 9196 ins_pipe(pipe_class_default); 9197 %} 9198 9199 // Immediate Multiplication 9200 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9201 match(Set dst (MulI src1 src2)); 9202 ins_cost(DEFAULT_COST); 9203 9204 format %{ "MULLI $dst, $src1, $src2" %} 9205 size(4); 9206 ins_encode %{ 9207 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9208 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9209 %} 9210 ins_pipe(pipe_class_default); 9211 %} 9212 9213 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9214 match(Set dst (MulL src1 src2)); 9215 ins_cost(DEFAULT_COST); 9216 9217 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9218 size(4); 9219 ins_encode %{ 9220 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9221 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9222 %} 9223 ins_pipe(pipe_class_default); 9224 %} 9225 9226 // Multiply high for optimized long division by constant. 9227 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9228 match(Set dst (MulHiL src1 src2)); 9229 ins_cost(DEFAULT_COST); 9230 9231 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9232 size(4); 9233 ins_encode %{ 9234 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9235 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9236 %} 9237 ins_pipe(pipe_class_default); 9238 %} 9239 9240 // Immediate Multiplication 9241 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9242 match(Set dst (MulL src1 src2)); 9243 ins_cost(DEFAULT_COST); 9244 9245 format %{ "MULLI $dst, $src1, $src2" %} 9246 size(4); 9247 ins_encode %{ 9248 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9249 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9250 %} 9251 ins_pipe(pipe_class_default); 9252 %} 9253 9254 // Integer Division with Immediate -1: Negate. 9255 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9256 match(Set dst (DivI src1 src2)); 9257 ins_cost(DEFAULT_COST); 9258 9259 format %{ "NEG $dst, $src1 \t// /-1" %} 9260 size(4); 9261 ins_encode %{ 9262 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9263 __ neg($dst$$Register, $src1$$Register); 9264 %} 9265 ins_pipe(pipe_class_default); 9266 %} 9267 9268 // Integer Division with constant, but not -1. 9269 // We should be able to improve this by checking the type of src2. 9270 // It might well be that src2 is known to be positive. 9271 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9272 match(Set dst (DivI src1 src2)); 9273 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9274 ins_cost(2*DEFAULT_COST); 9275 9276 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9277 size(4); 9278 ins_encode %{ 9279 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9280 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9281 %} 9282 ins_pipe(pipe_class_default); 9283 %} 9284 9285 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9286 effect(USE_DEF dst, USE src1, USE crx); 9287 predicate(false); 9288 9289 ins_variable_size_depending_on_alignment(true); 9290 9291 format %{ "CMOVE $dst, neg($src1), $crx" %} 9292 // Worst case is branch + move + stop, no stop without scheduler. 9293 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9294 ins_encode %{ 9295 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9296 Label done; 9297 __ bne($crx$$CondRegister, done); 9298 __ neg($dst$$Register, $src1$$Register); 9299 // TODO PPC port __ endgroup_if_needed(_size == 12); 9300 __ bind(done); 9301 %} 9302 ins_pipe(pipe_class_default); 9303 %} 9304 9305 // Integer Division with Registers not containing constants. 9306 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9307 match(Set dst (DivI src1 src2)); 9308 ins_cost(10*DEFAULT_COST); 9309 9310 expand %{ 9311 immI16 imm %{ (int)-1 %} 9312 flagsReg tmp1; 9313 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9314 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9315 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9316 %} 9317 %} 9318 9319 // Long Division with Immediate -1: Negate. 9320 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9321 match(Set dst (DivL src1 src2)); 9322 ins_cost(DEFAULT_COST); 9323 9324 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9325 size(4); 9326 ins_encode %{ 9327 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9328 __ neg($dst$$Register, $src1$$Register); 9329 %} 9330 ins_pipe(pipe_class_default); 9331 %} 9332 9333 // Long Division with constant, but not -1. 9334 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9335 match(Set dst (DivL src1 src2)); 9336 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9337 ins_cost(2*DEFAULT_COST); 9338 9339 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9340 size(4); 9341 ins_encode %{ 9342 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9343 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9344 %} 9345 ins_pipe(pipe_class_default); 9346 %} 9347 9348 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9349 effect(USE_DEF dst, USE src1, USE crx); 9350 predicate(false); 9351 9352 ins_variable_size_depending_on_alignment(true); 9353 9354 format %{ "CMOVE $dst, neg($src1), $crx" %} 9355 // Worst case is branch + move + stop, no stop without scheduler. 9356 size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 9357 ins_encode %{ 9358 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9359 Label done; 9360 __ bne($crx$$CondRegister, done); 9361 __ neg($dst$$Register, $src1$$Register); 9362 // TODO PPC port __ endgroup_if_needed(_size == 12); 9363 __ bind(done); 9364 %} 9365 ins_pipe(pipe_class_default); 9366 %} 9367 9368 // Long Division with Registers not containing constants. 9369 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9370 match(Set dst (DivL src1 src2)); 9371 ins_cost(10*DEFAULT_COST); 9372 9373 expand %{ 9374 immL16 imm %{ (int)-1 %} 9375 flagsReg tmp1; 9376 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9377 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9378 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9379 %} 9380 %} 9381 9382 // Integer Remainder with registers. 9383 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9384 match(Set dst (ModI src1 src2)); 9385 ins_cost(10*DEFAULT_COST); 9386 9387 expand %{ 9388 immI16 imm %{ (int)-1 %} 9389 flagsReg tmp1; 9390 iRegIdst tmp2; 9391 iRegIdst tmp3; 9392 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9393 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9394 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9395 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9396 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9397 %} 9398 %} 9399 9400 // Long Remainder with registers 9401 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9402 match(Set dst (ModL src1 src2)); 9403 ins_cost(10*DEFAULT_COST); 9404 9405 expand %{ 9406 immL16 imm %{ (int)-1 %} 9407 flagsReg tmp1; 9408 iRegLdst tmp2; 9409 iRegLdst tmp3; 9410 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9411 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9412 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9413 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9414 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9415 %} 9416 %} 9417 9418 // Integer Shift Instructions 9419 9420 // Register Shift Left 9421 9422 // Clear all but the lowest #mask bits. 9423 // Used to normalize shift amounts in registers. 9424 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9425 // no match-rule, false predicate 9426 effect(DEF dst, USE src, USE mask); 9427 predicate(false); 9428 9429 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9430 size(4); 9431 ins_encode %{ 9432 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9433 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9434 %} 9435 ins_pipe(pipe_class_default); 9436 %} 9437 9438 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9439 // no match-rule, false predicate 9440 effect(DEF dst, USE src1, USE src2); 9441 predicate(false); 9442 9443 format %{ "SLW $dst, $src1, $src2" %} 9444 size(4); 9445 ins_encode %{ 9446 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9447 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9448 %} 9449 ins_pipe(pipe_class_default); 9450 %} 9451 9452 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9453 match(Set dst (LShiftI src1 src2)); 9454 ins_cost(DEFAULT_COST*2); 9455 expand %{ 9456 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9457 iRegIdst tmpI; 9458 maskI_reg_imm(tmpI, src2, mask); 9459 lShiftI_reg_reg(dst, src1, tmpI); 9460 %} 9461 %} 9462 9463 // Register Shift Left Immediate 9464 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9465 match(Set dst (LShiftI src1 src2)); 9466 9467 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9471 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9472 %} 9473 ins_pipe(pipe_class_default); 9474 %} 9475 9476 // AndI with negpow2-constant + LShiftI 9477 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9478 match(Set dst (LShiftI (AndI src1 src2) src3)); 9479 predicate(UseRotateAndMaskInstructionsPPC64); 9480 9481 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9482 size(4); 9483 ins_encode %{ 9484 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9485 long src2 = $src2$$constant; 9486 long src3 = $src3$$constant; 9487 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9488 if (maskbits >= 32) { 9489 __ li($dst$$Register, 0); // addi 9490 } else { 9491 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9492 } 9493 %} 9494 ins_pipe(pipe_class_default); 9495 %} 9496 9497 // RShiftI + AndI with negpow2-constant + LShiftI 9498 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9499 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9500 predicate(UseRotateAndMaskInstructionsPPC64); 9501 9502 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9503 size(4); 9504 ins_encode %{ 9505 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9506 long src2 = $src2$$constant; 9507 long src3 = $src3$$constant; 9508 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9509 if (maskbits >= 32) { 9510 __ li($dst$$Register, 0); // addi 9511 } else { 9512 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9513 } 9514 %} 9515 ins_pipe(pipe_class_default); 9516 %} 9517 9518 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9519 // no match-rule, false predicate 9520 effect(DEF dst, USE src1, USE src2); 9521 predicate(false); 9522 9523 format %{ "SLD $dst, $src1, $src2" %} 9524 size(4); 9525 ins_encode %{ 9526 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9527 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9528 %} 9529 ins_pipe(pipe_class_default); 9530 %} 9531 9532 // Register Shift Left 9533 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9534 match(Set dst (LShiftL src1 src2)); 9535 ins_cost(DEFAULT_COST*2); 9536 expand %{ 9537 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9538 iRegIdst tmpI; 9539 maskI_reg_imm(tmpI, src2, mask); 9540 lShiftL_regL_regI(dst, src1, tmpI); 9541 %} 9542 %} 9543 9544 // Register Shift Left Immediate 9545 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9546 match(Set dst (LShiftL src1 src2)); 9547 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9548 size(4); 9549 ins_encode %{ 9550 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9551 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9552 %} 9553 ins_pipe(pipe_class_default); 9554 %} 9555 9556 // If we shift more than 32 bits, we need not convert I2L. 9557 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9558 match(Set dst (LShiftL (ConvI2L src1) src2)); 9559 ins_cost(DEFAULT_COST); 9560 9561 size(4); 9562 format %{ "SLDI $dst, i2l($src1), $src2" %} 9563 ins_encode %{ 9564 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9565 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9566 %} 9567 ins_pipe(pipe_class_default); 9568 %} 9569 9570 // Shift a postivie int to the left. 9571 // Clrlsldi clears the upper 32 bits and shifts. 9572 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9573 match(Set dst (LShiftL (ConvI2L src1) src2)); 9574 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9575 9576 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9577 size(4); 9578 ins_encode %{ 9579 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9580 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9581 %} 9582 ins_pipe(pipe_class_default); 9583 %} 9584 9585 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9586 // no match-rule, false predicate 9587 effect(DEF dst, USE src1, USE src2); 9588 predicate(false); 9589 9590 format %{ "SRAW $dst, $src1, $src2" %} 9591 size(4); 9592 ins_encode %{ 9593 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9594 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9595 %} 9596 ins_pipe(pipe_class_default); 9597 %} 9598 9599 // Register Arithmetic Shift Right 9600 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9601 match(Set dst (RShiftI src1 src2)); 9602 ins_cost(DEFAULT_COST*2); 9603 expand %{ 9604 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9605 iRegIdst tmpI; 9606 maskI_reg_imm(tmpI, src2, mask); 9607 arShiftI_reg_reg(dst, src1, tmpI); 9608 %} 9609 %} 9610 9611 // Register Arithmetic Shift Right Immediate 9612 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9613 match(Set dst (RShiftI src1 src2)); 9614 9615 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9616 size(4); 9617 ins_encode %{ 9618 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9619 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9620 %} 9621 ins_pipe(pipe_class_default); 9622 %} 9623 9624 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9625 // no match-rule, false predicate 9626 effect(DEF dst, USE src1, USE src2); 9627 predicate(false); 9628 9629 format %{ "SRAD $dst, $src1, $src2" %} 9630 size(4); 9631 ins_encode %{ 9632 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9633 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9634 %} 9635 ins_pipe(pipe_class_default); 9636 %} 9637 9638 // Register Shift Right Arithmetic Long 9639 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9640 match(Set dst (RShiftL src1 src2)); 9641 ins_cost(DEFAULT_COST*2); 9642 9643 expand %{ 9644 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9645 iRegIdst tmpI; 9646 maskI_reg_imm(tmpI, src2, mask); 9647 arShiftL_regL_regI(dst, src1, tmpI); 9648 %} 9649 %} 9650 9651 // Register Shift Right Immediate 9652 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9653 match(Set dst (RShiftL src1 src2)); 9654 9655 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9656 size(4); 9657 ins_encode %{ 9658 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9659 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9660 %} 9661 ins_pipe(pipe_class_default); 9662 %} 9663 9664 // RShiftL + ConvL2I 9665 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9666 match(Set dst (ConvL2I (RShiftL src1 src2))); 9667 9668 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9669 size(4); 9670 ins_encode %{ 9671 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9672 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9673 %} 9674 ins_pipe(pipe_class_default); 9675 %} 9676 9677 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9678 // no match-rule, false predicate 9679 effect(DEF dst, USE src1, USE src2); 9680 predicate(false); 9681 9682 format %{ "SRW $dst, $src1, $src2" %} 9683 size(4); 9684 ins_encode %{ 9685 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9686 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9687 %} 9688 ins_pipe(pipe_class_default); 9689 %} 9690 9691 // Register Shift Right 9692 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9693 match(Set dst (URShiftI src1 src2)); 9694 ins_cost(DEFAULT_COST*2); 9695 9696 expand %{ 9697 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9698 iRegIdst tmpI; 9699 maskI_reg_imm(tmpI, src2, mask); 9700 urShiftI_reg_reg(dst, src1, tmpI); 9701 %} 9702 %} 9703 9704 // Register Shift Right Immediate 9705 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9706 match(Set dst (URShiftI src1 src2)); 9707 9708 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9709 size(4); 9710 ins_encode %{ 9711 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9712 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9713 %} 9714 ins_pipe(pipe_class_default); 9715 %} 9716 9717 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9718 // no match-rule, false predicate 9719 effect(DEF dst, USE src1, USE src2); 9720 predicate(false); 9721 9722 format %{ "SRD $dst, $src1, $src2" %} 9723 size(4); 9724 ins_encode %{ 9725 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9726 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9727 %} 9728 ins_pipe(pipe_class_default); 9729 %} 9730 9731 // Register Shift Right 9732 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9733 match(Set dst (URShiftL src1 src2)); 9734 ins_cost(DEFAULT_COST*2); 9735 9736 expand %{ 9737 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9738 iRegIdst tmpI; 9739 maskI_reg_imm(tmpI, src2, mask); 9740 urShiftL_regL_regI(dst, src1, tmpI); 9741 %} 9742 %} 9743 9744 // Register Shift Right Immediate 9745 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9746 match(Set dst (URShiftL src1 src2)); 9747 9748 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9749 size(4); 9750 ins_encode %{ 9751 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9752 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9753 %} 9754 ins_pipe(pipe_class_default); 9755 %} 9756 9757 // URShiftL + ConvL2I. 9758 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9759 match(Set dst (ConvL2I (URShiftL src1 src2))); 9760 9761 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9762 size(4); 9763 ins_encode %{ 9764 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9765 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9766 %} 9767 ins_pipe(pipe_class_default); 9768 %} 9769 9770 // Register Shift Right Immediate with a CastP2X 9771 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9772 match(Set dst (URShiftL (CastP2X src1) src2)); 9773 9774 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9775 size(4); 9776 ins_encode %{ 9777 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9778 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9779 %} 9780 ins_pipe(pipe_class_default); 9781 %} 9782 9783 // Bitfield Extract: URShiftI + AndI 9784 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9785 match(Set dst (AndI (URShiftI src1 src2) src3)); 9786 9787 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9788 size(4); 9789 ins_encode %{ 9790 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9791 int rshift = ($src2$$constant) & 0x1f; 9792 int length = log2_long(((jlong) $src3$$constant) + 1); 9793 if (rshift + length > 32) { 9794 // if necessary, adjust mask to omit rotated bits. 9795 length = 32 - rshift; 9796 } 9797 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9798 %} 9799 ins_pipe(pipe_class_default); 9800 %} 9801 9802 // Bitfield Extract: URShiftL + AndL 9803 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9804 match(Set dst (AndL (URShiftL src1 src2) src3)); 9805 9806 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9807 size(4); 9808 ins_encode %{ 9809 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9810 int rshift = ($src2$$constant) & 0x3f; 9811 int length = log2_long(((jlong) $src3$$constant) + 1); 9812 if (rshift + length > 64) { 9813 // if necessary, adjust mask to omit rotated bits. 9814 length = 64 - rshift; 9815 } 9816 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9817 %} 9818 ins_pipe(pipe_class_default); 9819 %} 9820 9821 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9822 match(Set dst (ConvL2I (ConvI2L src))); 9823 9824 format %{ "EXTSW $dst, $src \t// int->int" %} 9825 size(4); 9826 ins_encode %{ 9827 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9828 __ extsw($dst$$Register, $src$$Register); 9829 %} 9830 ins_pipe(pipe_class_default); 9831 %} 9832 9833 //----------Rotate Instructions------------------------------------------------ 9834 9835 // Rotate Left by 8-bit immediate 9836 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9837 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9838 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9839 9840 format %{ "ROTLWI $dst, $src, $lshift" %} 9841 size(4); 9842 ins_encode %{ 9843 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9844 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9845 %} 9846 ins_pipe(pipe_class_default); 9847 %} 9848 9849 // Rotate Right by 8-bit immediate 9850 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9851 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9852 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9853 9854 format %{ "ROTRWI $dst, $rshift" %} 9855 size(4); 9856 ins_encode %{ 9857 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9858 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9859 %} 9860 ins_pipe(pipe_class_default); 9861 %} 9862 9863 //----------Floating Point Arithmetic Instructions----------------------------- 9864 9865 // Add float single precision 9866 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9867 match(Set dst (AddF src1 src2)); 9868 9869 format %{ "FADDS $dst, $src1, $src2" %} 9870 size(4); 9871 ins_encode %{ 9872 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9873 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9874 %} 9875 ins_pipe(pipe_class_default); 9876 %} 9877 9878 // Add float double precision 9879 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9880 match(Set dst (AddD src1 src2)); 9881 9882 format %{ "FADD $dst, $src1, $src2" %} 9883 size(4); 9884 ins_encode %{ 9885 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9886 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 // Sub float single precision 9892 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9893 match(Set dst (SubF src1 src2)); 9894 9895 format %{ "FSUBS $dst, $src1, $src2" %} 9896 size(4); 9897 ins_encode %{ 9898 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9899 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9900 %} 9901 ins_pipe(pipe_class_default); 9902 %} 9903 9904 // Sub float double precision 9905 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9906 match(Set dst (SubD src1 src2)); 9907 format %{ "FSUB $dst, $src1, $src2" %} 9908 size(4); 9909 ins_encode %{ 9910 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9911 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9912 %} 9913 ins_pipe(pipe_class_default); 9914 %} 9915 9916 // Mul float single precision 9917 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9918 match(Set dst (MulF src1 src2)); 9919 format %{ "FMULS $dst, $src1, $src2" %} 9920 size(4); 9921 ins_encode %{ 9922 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9923 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9924 %} 9925 ins_pipe(pipe_class_default); 9926 %} 9927 9928 // Mul float double precision 9929 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9930 match(Set dst (MulD src1 src2)); 9931 format %{ "FMUL $dst, $src1, $src2" %} 9932 size(4); 9933 ins_encode %{ 9934 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9935 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9936 %} 9937 ins_pipe(pipe_class_default); 9938 %} 9939 9940 // Div float single precision 9941 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9942 match(Set dst (DivF src1 src2)); 9943 format %{ "FDIVS $dst, $src1, $src2" %} 9944 size(4); 9945 ins_encode %{ 9946 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9947 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9948 %} 9949 ins_pipe(pipe_class_default); 9950 %} 9951 9952 // Div float double precision 9953 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9954 match(Set dst (DivD src1 src2)); 9955 format %{ "FDIV $dst, $src1, $src2" %} 9956 size(4); 9957 ins_encode %{ 9958 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9959 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9960 %} 9961 ins_pipe(pipe_class_default); 9962 %} 9963 9964 // Absolute float single precision 9965 instruct absF_reg(regF dst, regF src) %{ 9966 match(Set dst (AbsF src)); 9967 format %{ "FABS $dst, $src \t// float" %} 9968 size(4); 9969 ins_encode %{ 9970 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9971 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9972 %} 9973 ins_pipe(pipe_class_default); 9974 %} 9975 9976 // Absolute float double precision 9977 instruct absD_reg(regD dst, regD src) %{ 9978 match(Set dst (AbsD src)); 9979 format %{ "FABS $dst, $src \t// double" %} 9980 size(4); 9981 ins_encode %{ 9982 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9983 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9984 %} 9985 ins_pipe(pipe_class_default); 9986 %} 9987 9988 instruct negF_reg(regF dst, regF src) %{ 9989 match(Set dst (NegF src)); 9990 format %{ "FNEG $dst, $src \t// float" %} 9991 size(4); 9992 ins_encode %{ 9993 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9994 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9995 %} 9996 ins_pipe(pipe_class_default); 9997 %} 9998 9999 instruct negD_reg(regD dst, regD src) %{ 10000 match(Set dst (NegD src)); 10001 format %{ "FNEG $dst, $src \t// double" %} 10002 size(4); 10003 ins_encode %{ 10004 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 10005 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 10006 %} 10007 ins_pipe(pipe_class_default); 10008 %} 10009 10010 // AbsF + NegF. 10011 instruct negF_absF_reg(regF dst, regF src) %{ 10012 match(Set dst (NegF (AbsF src))); 10013 format %{ "FNABS $dst, $src \t// float" %} 10014 size(4); 10015 ins_encode %{ 10016 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10017 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10018 %} 10019 ins_pipe(pipe_class_default); 10020 %} 10021 10022 // AbsD + NegD. 10023 instruct negD_absD_reg(regD dst, regD src) %{ 10024 match(Set dst (NegD (AbsD src))); 10025 format %{ "FNABS $dst, $src \t// double" %} 10026 size(4); 10027 ins_encode %{ 10028 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10029 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10030 %} 10031 ins_pipe(pipe_class_default); 10032 %} 10033 10034 // VM_Version::has_fsqrt() decides if this node will be used. 10035 // Sqrt float double precision 10036 instruct sqrtD_reg(regD dst, regD src) %{ 10037 match(Set dst (SqrtD src)); 10038 format %{ "FSQRT $dst, $src" %} 10039 size(4); 10040 ins_encode %{ 10041 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10042 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10043 %} 10044 ins_pipe(pipe_class_default); 10045 %} 10046 10047 // Single-precision sqrt. 10048 instruct sqrtF_reg(regF dst, regF src) %{ 10049 match(Set dst (SqrtF src)); 10050 predicate(VM_Version::has_fsqrts()); 10051 ins_cost(DEFAULT_COST); 10052 10053 format %{ "FSQRTS $dst, $src" %} 10054 size(4); 10055 ins_encode %{ 10056 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10057 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10058 %} 10059 ins_pipe(pipe_class_default); 10060 %} 10061 10062 instruct roundDouble_nop(regD dst) %{ 10063 match(Set dst (RoundDouble dst)); 10064 ins_cost(0); 10065 10066 format %{ " -- \t// RoundDouble not needed - empty" %} 10067 size(0); 10068 // PPC results are already "rounded" (i.e., normal-format IEEE). 10069 ins_encode( /*empty*/ ); 10070 ins_pipe(pipe_class_default); 10071 %} 10072 10073 instruct roundFloat_nop(regF dst) %{ 10074 match(Set dst (RoundFloat dst)); 10075 ins_cost(0); 10076 10077 format %{ " -- \t// RoundFloat not needed - empty" %} 10078 size(0); 10079 // PPC results are already "rounded" (i.e., normal-format IEEE). 10080 ins_encode( /*empty*/ ); 10081 ins_pipe(pipe_class_default); 10082 %} 10083 10084 10085 // Multiply-Accumulate 10086 // src1 * src2 + src3 10087 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10088 match(Set dst (FmaF src3 (Binary src1 src2))); 10089 10090 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10091 size(4); 10092 ins_encode %{ 10093 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10094 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10095 %} 10096 ins_pipe(pipe_class_default); 10097 %} 10098 10099 // src1 * src2 + src3 10100 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10101 match(Set dst (FmaD src3 (Binary src1 src2))); 10102 10103 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10104 size(4); 10105 ins_encode %{ 10106 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10107 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10108 %} 10109 ins_pipe(pipe_class_default); 10110 %} 10111 10112 // -src1 * src2 + src3 = -(src1*src2-src3) 10113 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10114 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10115 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10116 10117 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10118 size(4); 10119 ins_encode %{ 10120 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10121 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10122 %} 10123 ins_pipe(pipe_class_default); 10124 %} 10125 10126 // -src1 * src2 + src3 = -(src1*src2-src3) 10127 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10128 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10129 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10130 10131 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10132 size(4); 10133 ins_encode %{ 10134 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10135 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10136 %} 10137 ins_pipe(pipe_class_default); 10138 %} 10139 10140 // -src1 * src2 - src3 = -(src1*src2+src3) 10141 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10142 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10143 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10144 10145 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10146 size(4); 10147 ins_encode %{ 10148 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10149 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10150 %} 10151 ins_pipe(pipe_class_default); 10152 %} 10153 10154 // -src1 * src2 - src3 = -(src1*src2+src3) 10155 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10156 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10157 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10158 10159 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10160 size(4); 10161 ins_encode %{ 10162 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10163 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10164 %} 10165 ins_pipe(pipe_class_default); 10166 %} 10167 10168 // src1 * src2 - src3 10169 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10170 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10171 10172 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10173 size(4); 10174 ins_encode %{ 10175 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10176 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10177 %} 10178 ins_pipe(pipe_class_default); 10179 %} 10180 10181 // src1 * src2 - src3 10182 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10183 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10184 10185 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10186 size(4); 10187 ins_encode %{ 10188 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10189 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10190 %} 10191 ins_pipe(pipe_class_default); 10192 %} 10193 10194 10195 //----------Logical Instructions----------------------------------------------- 10196 10197 // And Instructions 10198 10199 // Register And 10200 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10201 match(Set dst (AndI src1 src2)); 10202 format %{ "AND $dst, $src1, $src2" %} 10203 size(4); 10204 ins_encode %{ 10205 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10206 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10207 %} 10208 ins_pipe(pipe_class_default); 10209 %} 10210 10211 // Left shifted Immediate And 10212 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10213 match(Set dst (AndI src1 src2)); 10214 effect(KILL cr0); 10215 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10216 size(4); 10217 ins_encode %{ 10218 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10219 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10220 %} 10221 ins_pipe(pipe_class_default); 10222 %} 10223 10224 // Immediate And 10225 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10226 match(Set dst (AndI src1 src2)); 10227 effect(KILL cr0); 10228 10229 format %{ "ANDI $dst, $src1, $src2" %} 10230 size(4); 10231 ins_encode %{ 10232 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10233 // FIXME: avoid andi_ ? 10234 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10235 %} 10236 ins_pipe(pipe_class_default); 10237 %} 10238 10239 // Immediate And where the immediate is a negative power of 2. 10240 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10241 match(Set dst (AndI src1 src2)); 10242 format %{ "ANDWI $dst, $src1, $src2" %} 10243 size(4); 10244 ins_encode %{ 10245 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10246 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10247 %} 10248 ins_pipe(pipe_class_default); 10249 %} 10250 10251 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10252 match(Set dst (AndI src1 src2)); 10253 format %{ "ANDWI $dst, $src1, $src2" %} 10254 size(4); 10255 ins_encode %{ 10256 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10257 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10258 %} 10259 ins_pipe(pipe_class_default); 10260 %} 10261 10262 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10263 match(Set dst (AndI src1 src2)); 10264 predicate(UseRotateAndMaskInstructionsPPC64); 10265 format %{ "ANDWI $dst, $src1, $src2" %} 10266 size(4); 10267 ins_encode %{ 10268 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10269 __ rlwinm($dst$$Register, $src1$$Register, 0, 10270 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10271 %} 10272 ins_pipe(pipe_class_default); 10273 %} 10274 10275 // Register And Long 10276 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10277 match(Set dst (AndL src1 src2)); 10278 ins_cost(DEFAULT_COST); 10279 10280 format %{ "AND $dst, $src1, $src2 \t// long" %} 10281 size(4); 10282 ins_encode %{ 10283 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10284 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10285 %} 10286 ins_pipe(pipe_class_default); 10287 %} 10288 10289 // Immediate And long 10290 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10291 match(Set dst (AndL src1 src2)); 10292 effect(KILL cr0); 10293 10294 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10295 size(4); 10296 ins_encode %{ 10297 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10298 // FIXME: avoid andi_ ? 10299 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10300 %} 10301 ins_pipe(pipe_class_default); 10302 %} 10303 10304 // Immediate And Long where the immediate is a negative power of 2. 10305 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10306 match(Set dst (AndL src1 src2)); 10307 format %{ "ANDDI $dst, $src1, $src2" %} 10308 size(4); 10309 ins_encode %{ 10310 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10311 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10312 %} 10313 ins_pipe(pipe_class_default); 10314 %} 10315 10316 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10317 match(Set dst (AndL src1 src2)); 10318 format %{ "ANDDI $dst, $src1, $src2" %} 10319 size(4); 10320 ins_encode %{ 10321 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10322 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10323 %} 10324 ins_pipe(pipe_class_default); 10325 %} 10326 10327 // AndL + ConvL2I. 10328 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10329 match(Set dst (ConvL2I (AndL src1 src2))); 10330 ins_cost(DEFAULT_COST); 10331 10332 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10333 size(4); 10334 ins_encode %{ 10335 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10336 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10337 %} 10338 ins_pipe(pipe_class_default); 10339 %} 10340 10341 // Or Instructions 10342 10343 // Register Or 10344 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10345 match(Set dst (OrI src1 src2)); 10346 format %{ "OR $dst, $src1, $src2" %} 10347 size(4); 10348 ins_encode %{ 10349 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10350 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10351 %} 10352 ins_pipe(pipe_class_default); 10353 %} 10354 10355 // Expand does not work with above instruct. (??) 10356 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10357 // no match-rule 10358 effect(DEF dst, USE src1, USE src2); 10359 format %{ "OR $dst, $src1, $src2" %} 10360 size(4); 10361 ins_encode %{ 10362 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10363 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10364 %} 10365 ins_pipe(pipe_class_default); 10366 %} 10367 10368 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10369 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10370 ins_cost(DEFAULT_COST*3); 10371 10372 expand %{ 10373 // FIXME: we should do this in the ideal world. 10374 iRegIdst tmp1; 10375 iRegIdst tmp2; 10376 orI_reg_reg(tmp1, src1, src2); 10377 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10378 orI_reg_reg(dst, tmp1, tmp2); 10379 %} 10380 %} 10381 10382 // Immediate Or 10383 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10384 match(Set dst (OrI src1 src2)); 10385 format %{ "ORI $dst, $src1, $src2" %} 10386 size(4); 10387 ins_encode %{ 10388 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10389 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10390 %} 10391 ins_pipe(pipe_class_default); 10392 %} 10393 10394 // Register Or Long 10395 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10396 match(Set dst (OrL src1 src2)); 10397 ins_cost(DEFAULT_COST); 10398 10399 size(4); 10400 format %{ "OR $dst, $src1, $src2 \t// long" %} 10401 ins_encode %{ 10402 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10403 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10404 %} 10405 ins_pipe(pipe_class_default); 10406 %} 10407 10408 // OrL + ConvL2I. 10409 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10410 match(Set dst (ConvL2I (OrL src1 src2))); 10411 ins_cost(DEFAULT_COST); 10412 10413 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10414 size(4); 10415 ins_encode %{ 10416 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10417 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10418 %} 10419 ins_pipe(pipe_class_default); 10420 %} 10421 10422 // Immediate Or long 10423 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10424 match(Set dst (OrL src1 con)); 10425 ins_cost(DEFAULT_COST); 10426 10427 format %{ "ORI $dst, $src1, $con \t// long" %} 10428 size(4); 10429 ins_encode %{ 10430 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10431 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10432 %} 10433 ins_pipe(pipe_class_default); 10434 %} 10435 10436 // Xor Instructions 10437 10438 // Register Xor 10439 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10440 match(Set dst (XorI src1 src2)); 10441 format %{ "XOR $dst, $src1, $src2" %} 10442 size(4); 10443 ins_encode %{ 10444 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10445 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10446 %} 10447 ins_pipe(pipe_class_default); 10448 %} 10449 10450 // Expand does not work with above instruct. (??) 10451 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10452 // no match-rule 10453 effect(DEF dst, USE src1, USE src2); 10454 format %{ "XOR $dst, $src1, $src2" %} 10455 size(4); 10456 ins_encode %{ 10457 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10458 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10459 %} 10460 ins_pipe(pipe_class_default); 10461 %} 10462 10463 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10464 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10465 ins_cost(DEFAULT_COST*3); 10466 10467 expand %{ 10468 // FIXME: we should do this in the ideal world. 10469 iRegIdst tmp1; 10470 iRegIdst tmp2; 10471 xorI_reg_reg(tmp1, src1, src2); 10472 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10473 xorI_reg_reg(dst, tmp1, tmp2); 10474 %} 10475 %} 10476 10477 // Immediate Xor 10478 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10479 match(Set dst (XorI src1 src2)); 10480 format %{ "XORI $dst, $src1, $src2" %} 10481 size(4); 10482 ins_encode %{ 10483 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10484 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10485 %} 10486 ins_pipe(pipe_class_default); 10487 %} 10488 10489 // Register Xor Long 10490 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10491 match(Set dst (XorL src1 src2)); 10492 ins_cost(DEFAULT_COST); 10493 10494 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10495 size(4); 10496 ins_encode %{ 10497 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10498 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10499 %} 10500 ins_pipe(pipe_class_default); 10501 %} 10502 10503 // XorL + ConvL2I. 10504 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10505 match(Set dst (ConvL2I (XorL src1 src2))); 10506 ins_cost(DEFAULT_COST); 10507 10508 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10509 size(4); 10510 ins_encode %{ 10511 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10512 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10513 %} 10514 ins_pipe(pipe_class_default); 10515 %} 10516 10517 // Immediate Xor Long 10518 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10519 match(Set dst (XorL src1 src2)); 10520 ins_cost(DEFAULT_COST); 10521 10522 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10523 size(4); 10524 ins_encode %{ 10525 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10526 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10527 %} 10528 ins_pipe(pipe_class_default); 10529 %} 10530 10531 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10532 match(Set dst (XorI src1 src2)); 10533 ins_cost(DEFAULT_COST); 10534 10535 format %{ "NOT $dst, $src1 ($src2)" %} 10536 size(4); 10537 ins_encode %{ 10538 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10539 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10540 %} 10541 ins_pipe(pipe_class_default); 10542 %} 10543 10544 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10545 match(Set dst (XorL src1 src2)); 10546 ins_cost(DEFAULT_COST); 10547 10548 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10549 size(4); 10550 ins_encode %{ 10551 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10552 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10553 %} 10554 ins_pipe(pipe_class_default); 10555 %} 10556 10557 // And-complement 10558 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10559 match(Set dst (AndI (XorI src1 src2) src3)); 10560 ins_cost(DEFAULT_COST); 10561 10562 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10563 size(4); 10564 ins_encode( enc_andc(dst, src3, src1) ); 10565 ins_pipe(pipe_class_default); 10566 %} 10567 10568 // And-complement 10569 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10570 // no match-rule, false predicate 10571 effect(DEF dst, USE src1, USE src2); 10572 predicate(false); 10573 10574 format %{ "ANDC $dst, $src1, $src2" %} 10575 size(4); 10576 ins_encode %{ 10577 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10578 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10579 %} 10580 ins_pipe(pipe_class_default); 10581 %} 10582 10583 //----------Moves between int/long and float/double---------------------------- 10584 // 10585 // The following rules move values from int/long registers/stack-locations 10586 // to float/double registers/stack-locations and vice versa, without doing any 10587 // conversions. These rules are used to implement the bit-conversion methods 10588 // of java.lang.Float etc., e.g. 10589 // int floatToIntBits(float value) 10590 // float intBitsToFloat(int bits) 10591 // 10592 // Notes on the implementation on ppc64: 10593 // For Power7 and earlier, the rules are limited to those which move between a 10594 // register and a stack-location, because we always have to go through memory 10595 // when moving between a float register and an integer register. 10596 // This restriction is removed in Power8 with the introduction of the mtfprd 10597 // and mffprd instructions. 10598 10599 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10600 match(Set dst (MoveL2D src)); 10601 predicate(VM_Version::has_mtfprd()); 10602 10603 format %{ "MTFPRD $dst, $src" %} 10604 size(4); 10605 ins_encode %{ 10606 __ mtfprd($dst$$FloatRegister, $src$$Register); 10607 %} 10608 ins_pipe(pipe_class_default); 10609 %} 10610 10611 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10612 // no match-rule, false predicate 10613 effect(DEF dst, USE src); 10614 predicate(false); 10615 10616 format %{ "MTFPRWA $dst, $src" %} 10617 size(4); 10618 ins_encode %{ 10619 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10620 %} 10621 ins_pipe(pipe_class_default); 10622 %} 10623 10624 //---------- Chain stack slots between similar types -------- 10625 10626 // These are needed so that the rules below can match. 10627 10628 // Load integer from stack slot 10629 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10630 match(Set dst src); 10631 ins_cost(MEMORY_REF_COST); 10632 10633 format %{ "LWZ $dst, $src" %} 10634 size(4); 10635 ins_encode( enc_lwz(dst, src) ); 10636 ins_pipe(pipe_class_memory); 10637 %} 10638 10639 // Store integer to stack slot 10640 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10641 match(Set dst src); 10642 ins_cost(MEMORY_REF_COST); 10643 10644 format %{ "STW $src, $dst \t// stk" %} 10645 size(4); 10646 ins_encode( enc_stw(src, dst) ); // rs=rt 10647 ins_pipe(pipe_class_memory); 10648 %} 10649 10650 // Load long from stack slot 10651 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10652 match(Set dst src); 10653 ins_cost(MEMORY_REF_COST); 10654 10655 format %{ "LD $dst, $src \t// long" %} 10656 size(4); 10657 ins_encode( enc_ld(dst, src) ); 10658 ins_pipe(pipe_class_memory); 10659 %} 10660 10661 // Store long to stack slot 10662 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10663 match(Set dst src); 10664 ins_cost(MEMORY_REF_COST); 10665 10666 format %{ "STD $src, $dst \t// long" %} 10667 size(4); 10668 ins_encode( enc_std(src, dst) ); // rs=rt 10669 ins_pipe(pipe_class_memory); 10670 %} 10671 10672 //----------Moves between int and float 10673 10674 // Move float value from float stack-location to integer register. 10675 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10676 match(Set dst (MoveF2I src)); 10677 ins_cost(MEMORY_REF_COST); 10678 10679 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10680 size(4); 10681 ins_encode( enc_lwz(dst, src) ); 10682 ins_pipe(pipe_class_memory); 10683 %} 10684 10685 // Move float value from float register to integer stack-location. 10686 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10687 match(Set dst (MoveF2I src)); 10688 ins_cost(MEMORY_REF_COST); 10689 10690 format %{ "STFS $src, $dst \t// MoveF2I" %} 10691 size(4); 10692 ins_encode( enc_stfs(src, dst) ); 10693 ins_pipe(pipe_class_memory); 10694 %} 10695 10696 // Move integer value from integer stack-location to float register. 10697 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10698 match(Set dst (MoveI2F src)); 10699 ins_cost(MEMORY_REF_COST); 10700 10701 format %{ "LFS $dst, $src \t// MoveI2F" %} 10702 size(4); 10703 ins_encode %{ 10704 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10705 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10706 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10707 %} 10708 ins_pipe(pipe_class_memory); 10709 %} 10710 10711 // Move integer value from integer register to float stack-location. 10712 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10713 match(Set dst (MoveI2F src)); 10714 ins_cost(MEMORY_REF_COST); 10715 10716 format %{ "STW $src, $dst \t// MoveI2F" %} 10717 size(4); 10718 ins_encode( enc_stw(src, dst) ); 10719 ins_pipe(pipe_class_memory); 10720 %} 10721 10722 //----------Moves between long and float 10723 10724 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10725 // no match-rule, false predicate 10726 effect(DEF dst, USE src); 10727 predicate(false); 10728 10729 format %{ "storeD $src, $dst \t// STACK" %} 10730 size(4); 10731 ins_encode( enc_stfd(src, dst) ); 10732 ins_pipe(pipe_class_default); 10733 %} 10734 10735 //----------Moves between long and double 10736 10737 // Move double value from double stack-location to long register. 10738 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10739 match(Set dst (MoveD2L src)); 10740 ins_cost(MEMORY_REF_COST); 10741 size(4); 10742 format %{ "LD $dst, $src \t// MoveD2L" %} 10743 ins_encode( enc_ld(dst, src) ); 10744 ins_pipe(pipe_class_memory); 10745 %} 10746 10747 // Move double value from double register to long stack-location. 10748 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10749 match(Set dst (MoveD2L src)); 10750 effect(DEF dst, USE src); 10751 ins_cost(MEMORY_REF_COST); 10752 10753 format %{ "STFD $src, $dst \t// MoveD2L" %} 10754 size(4); 10755 ins_encode( enc_stfd(src, dst) ); 10756 ins_pipe(pipe_class_memory); 10757 %} 10758 10759 // Move long value from long stack-location to double register. 10760 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10761 match(Set dst (MoveL2D src)); 10762 ins_cost(MEMORY_REF_COST); 10763 10764 format %{ "LFD $dst, $src \t// MoveL2D" %} 10765 size(4); 10766 ins_encode( enc_lfd(dst, src) ); 10767 ins_pipe(pipe_class_memory); 10768 %} 10769 10770 // Move long value from long register to double stack-location. 10771 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10772 match(Set dst (MoveL2D src)); 10773 ins_cost(MEMORY_REF_COST); 10774 10775 format %{ "STD $src, $dst \t// MoveL2D" %} 10776 size(4); 10777 ins_encode( enc_std(src, dst) ); 10778 ins_pipe(pipe_class_memory); 10779 %} 10780 10781 //----------Register Move Instructions----------------------------------------- 10782 10783 // Replicate for Superword 10784 10785 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10786 predicate(false); 10787 effect(DEF dst, USE src); 10788 10789 format %{ "MR $dst, $src \t// replicate " %} 10790 // variable size, 0 or 4. 10791 ins_encode %{ 10792 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10793 __ mr_if_needed($dst$$Register, $src$$Register); 10794 %} 10795 ins_pipe(pipe_class_default); 10796 %} 10797 10798 //----------Cast instructions (Java-level type cast)--------------------------- 10799 10800 // Cast Long to Pointer for unsafe natives. 10801 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10802 match(Set dst (CastX2P src)); 10803 10804 format %{ "MR $dst, $src \t// Long->Ptr" %} 10805 // variable size, 0 or 4. 10806 ins_encode %{ 10807 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10808 __ mr_if_needed($dst$$Register, $src$$Register); 10809 %} 10810 ins_pipe(pipe_class_default); 10811 %} 10812 10813 // Cast Pointer to Long for unsafe natives. 10814 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10815 match(Set dst (CastP2X src)); 10816 10817 format %{ "MR $dst, $src \t// Ptr->Long" %} 10818 // variable size, 0 or 4. 10819 ins_encode %{ 10820 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10821 __ mr_if_needed($dst$$Register, $src$$Register); 10822 %} 10823 ins_pipe(pipe_class_default); 10824 %} 10825 10826 instruct castPP(iRegPdst dst) %{ 10827 match(Set dst (CastPP dst)); 10828 format %{ " -- \t// castPP of $dst" %} 10829 size(0); 10830 ins_encode( /*empty*/ ); 10831 ins_pipe(pipe_class_default); 10832 %} 10833 10834 instruct castII(iRegIdst dst) %{ 10835 match(Set dst (CastII dst)); 10836 format %{ " -- \t// castII of $dst" %} 10837 size(0); 10838 ins_encode( /*empty*/ ); 10839 ins_pipe(pipe_class_default); 10840 %} 10841 10842 instruct checkCastPP(iRegPdst dst) %{ 10843 match(Set dst (CheckCastPP dst)); 10844 format %{ " -- \t// checkcastPP of $dst" %} 10845 size(0); 10846 ins_encode( /*empty*/ ); 10847 ins_pipe(pipe_class_default); 10848 %} 10849 10850 //----------Convert instructions----------------------------------------------- 10851 10852 // Convert to boolean. 10853 10854 // int_to_bool(src) : { 1 if src != 0 10855 // { 0 else 10856 // 10857 // strategy: 10858 // 1) Count leading zeros of 32 bit-value src, 10859 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10860 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10861 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10862 10863 // convI2Bool 10864 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10865 match(Set dst (Conv2B src)); 10866 predicate(UseCountLeadingZerosInstructionsPPC64); 10867 ins_cost(DEFAULT_COST); 10868 10869 expand %{ 10870 immI shiftAmount %{ 0x5 %} 10871 uimmI16 mask %{ 0x1 %} 10872 iRegIdst tmp1; 10873 iRegIdst tmp2; 10874 countLeadingZerosI(tmp1, src); 10875 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10876 xorI_reg_uimm16(dst, tmp2, mask); 10877 %} 10878 %} 10879 10880 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10881 match(Set dst (Conv2B src)); 10882 effect(TEMP crx); 10883 predicate(!UseCountLeadingZerosInstructionsPPC64); 10884 ins_cost(DEFAULT_COST); 10885 10886 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10887 "LI $dst, #0\n\t" 10888 "BEQ $crx, done\n\t" 10889 "LI $dst, #1\n" 10890 "done:" %} 10891 size(16); 10892 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10893 ins_pipe(pipe_class_compare); 10894 %} 10895 10896 // ConvI2B + XorI 10897 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10898 match(Set dst (XorI (Conv2B src) mask)); 10899 predicate(UseCountLeadingZerosInstructionsPPC64); 10900 ins_cost(DEFAULT_COST); 10901 10902 expand %{ 10903 immI shiftAmount %{ 0x5 %} 10904 iRegIdst tmp1; 10905 countLeadingZerosI(tmp1, src); 10906 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10907 %} 10908 %} 10909 10910 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10911 match(Set dst (XorI (Conv2B src) mask)); 10912 effect(TEMP crx); 10913 predicate(!UseCountLeadingZerosInstructionsPPC64); 10914 ins_cost(DEFAULT_COST); 10915 10916 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10917 "LI $dst, #1\n\t" 10918 "BEQ $crx, done\n\t" 10919 "LI $dst, #0\n" 10920 "done:" %} 10921 size(16); 10922 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10923 ins_pipe(pipe_class_compare); 10924 %} 10925 10926 // AndI 0b0..010..0 + ConvI2B 10927 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10928 match(Set dst (Conv2B (AndI src mask))); 10929 predicate(UseRotateAndMaskInstructionsPPC64); 10930 ins_cost(DEFAULT_COST); 10931 10932 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10933 size(4); 10934 ins_encode %{ 10935 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10936 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10937 %} 10938 ins_pipe(pipe_class_default); 10939 %} 10940 10941 // Convert pointer to boolean. 10942 // 10943 // ptr_to_bool(src) : { 1 if src != 0 10944 // { 0 else 10945 // 10946 // strategy: 10947 // 1) Count leading zeros of 64 bit-value src, 10948 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10949 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10950 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10951 10952 // ConvP2B 10953 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10954 match(Set dst (Conv2B src)); 10955 predicate(UseCountLeadingZerosInstructionsPPC64); 10956 ins_cost(DEFAULT_COST); 10957 10958 expand %{ 10959 immI shiftAmount %{ 0x6 %} 10960 uimmI16 mask %{ 0x1 %} 10961 iRegIdst tmp1; 10962 iRegIdst tmp2; 10963 countLeadingZerosP(tmp1, src); 10964 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10965 xorI_reg_uimm16(dst, tmp2, mask); 10966 %} 10967 %} 10968 10969 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10970 match(Set dst (Conv2B src)); 10971 effect(TEMP crx); 10972 predicate(!UseCountLeadingZerosInstructionsPPC64); 10973 ins_cost(DEFAULT_COST); 10974 10975 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10976 "LI $dst, #0\n\t" 10977 "BEQ $crx, done\n\t" 10978 "LI $dst, #1\n" 10979 "done:" %} 10980 size(16); 10981 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10982 ins_pipe(pipe_class_compare); 10983 %} 10984 10985 // ConvP2B + XorI 10986 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10987 match(Set dst (XorI (Conv2B src) mask)); 10988 predicate(UseCountLeadingZerosInstructionsPPC64); 10989 ins_cost(DEFAULT_COST); 10990 10991 expand %{ 10992 immI shiftAmount %{ 0x6 %} 10993 iRegIdst tmp1; 10994 countLeadingZerosP(tmp1, src); 10995 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10996 %} 10997 %} 10998 10999 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 11000 match(Set dst (XorI (Conv2B src) mask)); 11001 effect(TEMP crx); 11002 predicate(!UseCountLeadingZerosInstructionsPPC64); 11003 ins_cost(DEFAULT_COST); 11004 11005 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 11006 "LI $dst, #1\n\t" 11007 "BEQ $crx, done\n\t" 11008 "LI $dst, #0\n" 11009 "done:" %} 11010 size(16); 11011 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 11012 ins_pipe(pipe_class_compare); 11013 %} 11014 11015 // if src1 < src2, return -1 else return 0 11016 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 11017 match(Set dst (CmpLTMask src1 src2)); 11018 ins_cost(DEFAULT_COST*4); 11019 11020 expand %{ 11021 iRegLdst src1s; 11022 iRegLdst src2s; 11023 iRegLdst diff; 11024 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11025 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11026 subL_reg_reg(diff, src1s, src2s); 11027 // Need to consider >=33 bit result, therefore we need signmaskL. 11028 signmask64I_regL(dst, diff); 11029 %} 11030 %} 11031 11032 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11033 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11034 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11035 size(4); 11036 ins_encode %{ 11037 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11038 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11039 %} 11040 ins_pipe(pipe_class_default); 11041 %} 11042 11043 //----------Arithmetic Conversion Instructions--------------------------------- 11044 11045 // Convert to Byte -- nop 11046 // Convert to Short -- nop 11047 11048 // Convert to Int 11049 11050 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11051 match(Set dst (RShiftI (LShiftI src amount) amount)); 11052 format %{ "EXTSB $dst, $src \t// byte->int" %} 11053 size(4); 11054 ins_encode %{ 11055 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11056 __ extsb($dst$$Register, $src$$Register); 11057 %} 11058 ins_pipe(pipe_class_default); 11059 %} 11060 11061 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11062 effect(DEF dst, USE src); 11063 11064 size(4); 11065 ins_encode %{ 11066 __ extsh($dst$$Register, $src$$Register); 11067 %} 11068 ins_pipe(pipe_class_default); 11069 %} 11070 11071 // LShiftI 16 + RShiftI 16 converts short to int. 11072 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11073 match(Set dst (RShiftI (LShiftI src amount) amount)); 11074 format %{ "EXTSH $dst, $src \t// short->int" %} 11075 size(4); 11076 ins_encode %{ 11077 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11078 __ extsh($dst$$Register, $src$$Register); 11079 %} 11080 ins_pipe(pipe_class_default); 11081 %} 11082 11083 // ConvL2I + ConvI2L: Sign extend int in long register. 11084 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11085 match(Set dst (ConvI2L (ConvL2I src))); 11086 11087 format %{ "EXTSW $dst, $src \t// long->long" %} 11088 size(4); 11089 ins_encode %{ 11090 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11091 __ extsw($dst$$Register, $src$$Register); 11092 %} 11093 ins_pipe(pipe_class_default); 11094 %} 11095 11096 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11097 match(Set dst (ConvL2I src)); 11098 format %{ "MR $dst, $src \t// long->int" %} 11099 // variable size, 0 or 4 11100 ins_encode %{ 11101 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11102 __ mr_if_needed($dst$$Register, $src$$Register); 11103 %} 11104 ins_pipe(pipe_class_default); 11105 %} 11106 11107 instruct convD2IRaw_regD(regD dst, regD src) %{ 11108 // no match-rule, false predicate 11109 effect(DEF dst, USE src); 11110 predicate(false); 11111 11112 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11113 size(4); 11114 ins_encode %{ 11115 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11116 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11117 %} 11118 ins_pipe(pipe_class_default); 11119 %} 11120 11121 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11122 // no match-rule, false predicate 11123 effect(DEF dst, USE crx, USE src); 11124 predicate(false); 11125 11126 ins_variable_size_depending_on_alignment(true); 11127 11128 format %{ "cmovI $crx, $dst, $src" %} 11129 // Worst case is branch + move + stop, no stop without scheduler. 11130 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11131 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11132 ins_pipe(pipe_class_default); 11133 %} 11134 11135 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11136 // no match-rule, false predicate 11137 effect(DEF dst, USE crx, USE src); 11138 predicate(false); 11139 11140 ins_variable_size_depending_on_alignment(true); 11141 11142 format %{ "cmovI $crx, $dst, $src" %} 11143 // Worst case is branch + move + stop, no stop without scheduler. 11144 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8)); 11145 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11146 ins_pipe(pipe_class_default); 11147 %} 11148 11149 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11150 // no match-rule, false predicate 11151 effect(DEF dst, USE crx, USE mem); 11152 predicate(false); 11153 11154 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11155 postalloc_expand %{ 11156 // 11157 // replaces 11158 // 11159 // region dst crx mem 11160 // \ | | / 11161 // dst=cmovI_bso_stackSlotL_conLvalue0 11162 // 11163 // with 11164 // 11165 // region dst 11166 // \ / 11167 // dst=loadConI16(0) 11168 // | 11169 // ^ region dst crx mem 11170 // | \ | | / 11171 // dst=cmovI_bso_stackSlotL 11172 // 11173 11174 // Create new nodes. 11175 MachNode *m1 = new loadConI16Node(); 11176 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11177 11178 // inputs for new nodes 11179 m1->add_req(n_region); 11180 m2->add_req(n_region, n_crx, n_mem); 11181 11182 // precedences for new nodes 11183 m2->add_prec(m1); 11184 11185 // operands for new nodes 11186 m1->_opnds[0] = op_dst; 11187 m1->_opnds[1] = new immI16Oper(0); 11188 11189 m2->_opnds[0] = op_dst; 11190 m2->_opnds[1] = op_crx; 11191 m2->_opnds[2] = op_mem; 11192 11193 // registers for new nodes 11194 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11195 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11196 11197 // Insert new nodes. 11198 nodes->push(m1); 11199 nodes->push(m2); 11200 %} 11201 %} 11202 11203 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11204 // no match-rule, false predicate 11205 effect(DEF dst, USE crx, USE src); 11206 predicate(false); 11207 11208 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11209 postalloc_expand %{ 11210 // 11211 // replaces 11212 // 11213 // region dst crx src 11214 // \ | | / 11215 // dst=cmovI_bso_reg_conLvalue0 11216 // 11217 // with 11218 // 11219 // region dst 11220 // \ / 11221 // dst=loadConI16(0) 11222 // | 11223 // ^ region dst crx src 11224 // | \ | | / 11225 // dst=cmovI_bso_reg 11226 // 11227 11228 // Create new nodes. 11229 MachNode *m1 = new loadConI16Node(); 11230 MachNode *m2 = new cmovI_bso_regNode(); 11231 11232 // inputs for new nodes 11233 m1->add_req(n_region); 11234 m2->add_req(n_region, n_crx, n_src); 11235 11236 // precedences for new nodes 11237 m2->add_prec(m1); 11238 11239 // operands for new nodes 11240 m1->_opnds[0] = op_dst; 11241 m1->_opnds[1] = new immI16Oper(0); 11242 11243 m2->_opnds[0] = op_dst; 11244 m2->_opnds[1] = op_crx; 11245 m2->_opnds[2] = op_src; 11246 11247 // registers for new nodes 11248 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11249 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11250 11251 // Insert new nodes. 11252 nodes->push(m1); 11253 nodes->push(m2); 11254 %} 11255 %} 11256 11257 // Double to Int conversion, NaN is mapped to 0. 11258 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11259 match(Set dst (ConvD2I src)); 11260 predicate(!VM_Version::has_mtfprd()); 11261 ins_cost(DEFAULT_COST); 11262 11263 expand %{ 11264 regD tmpD; 11265 stackSlotL tmpS; 11266 flagsReg crx; 11267 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11268 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11269 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11270 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11271 %} 11272 %} 11273 11274 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11275 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11276 match(Set dst (ConvD2I src)); 11277 predicate(VM_Version::has_mtfprd()); 11278 ins_cost(DEFAULT_COST); 11279 11280 expand %{ 11281 regD tmpD; 11282 flagsReg crx; 11283 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11284 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11285 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11286 %} 11287 %} 11288 11289 instruct convF2IRaw_regF(regF dst, regF src) %{ 11290 // no match-rule, false predicate 11291 effect(DEF dst, USE src); 11292 predicate(false); 11293 11294 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11295 size(4); 11296 ins_encode %{ 11297 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11298 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11299 %} 11300 ins_pipe(pipe_class_default); 11301 %} 11302 11303 // Float to Int conversion, NaN is mapped to 0. 11304 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11305 match(Set dst (ConvF2I src)); 11306 predicate(!VM_Version::has_mtfprd()); 11307 ins_cost(DEFAULT_COST); 11308 11309 expand %{ 11310 regF tmpF; 11311 stackSlotL tmpS; 11312 flagsReg crx; 11313 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11314 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11315 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11316 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11317 %} 11318 %} 11319 11320 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11321 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11322 match(Set dst (ConvF2I src)); 11323 predicate(VM_Version::has_mtfprd()); 11324 ins_cost(DEFAULT_COST); 11325 11326 expand %{ 11327 regF tmpF; 11328 flagsReg crx; 11329 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11330 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11331 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11332 %} 11333 %} 11334 11335 // Convert to Long 11336 11337 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11338 match(Set dst (ConvI2L src)); 11339 format %{ "EXTSW $dst, $src \t// int->long" %} 11340 size(4); 11341 ins_encode %{ 11342 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11343 __ extsw($dst$$Register, $src$$Register); 11344 %} 11345 ins_pipe(pipe_class_default); 11346 %} 11347 11348 // Zero-extend: convert unsigned int to long (convUI2L). 11349 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11350 match(Set dst (AndL (ConvI2L src) mask)); 11351 ins_cost(DEFAULT_COST); 11352 11353 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11354 size(4); 11355 ins_encode %{ 11356 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11357 __ clrldi($dst$$Register, $src$$Register, 32); 11358 %} 11359 ins_pipe(pipe_class_default); 11360 %} 11361 11362 // Zero-extend: convert unsigned int to long in long register. 11363 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11364 match(Set dst (AndL src mask)); 11365 ins_cost(DEFAULT_COST); 11366 11367 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11368 size(4); 11369 ins_encode %{ 11370 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11371 __ clrldi($dst$$Register, $src$$Register, 32); 11372 %} 11373 ins_pipe(pipe_class_default); 11374 %} 11375 11376 instruct convF2LRaw_regF(regF dst, regF src) %{ 11377 // no match-rule, false predicate 11378 effect(DEF dst, USE src); 11379 predicate(false); 11380 11381 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11382 size(4); 11383 ins_encode %{ 11384 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11385 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11386 %} 11387 ins_pipe(pipe_class_default); 11388 %} 11389 11390 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11391 // no match-rule, false predicate 11392 effect(DEF dst, USE crx, USE src); 11393 predicate(false); 11394 11395 ins_variable_size_depending_on_alignment(true); 11396 11397 format %{ "cmovL $crx, $dst, $src" %} 11398 // Worst case is branch + move + stop, no stop without scheduler. 11399 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11400 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11401 ins_pipe(pipe_class_default); 11402 %} 11403 11404 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11405 // no match-rule, false predicate 11406 effect(DEF dst, USE crx, USE src); 11407 predicate(false); 11408 11409 ins_variable_size_depending_on_alignment(true); 11410 11411 format %{ "cmovL $crx, $dst, $src" %} 11412 // Worst case is branch + move + stop, no stop without scheduler. 11413 size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8)); 11414 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11415 ins_pipe(pipe_class_default); 11416 %} 11417 11418 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11419 // no match-rule, false predicate 11420 effect(DEF dst, USE crx, USE mem); 11421 predicate(false); 11422 11423 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11424 postalloc_expand %{ 11425 // 11426 // replaces 11427 // 11428 // region dst crx mem 11429 // \ | | / 11430 // dst=cmovL_bso_stackSlotL_conLvalue0 11431 // 11432 // with 11433 // 11434 // region dst 11435 // \ / 11436 // dst=loadConL16(0) 11437 // | 11438 // ^ region dst crx mem 11439 // | \ | | / 11440 // dst=cmovL_bso_stackSlotL 11441 // 11442 11443 // Create new nodes. 11444 MachNode *m1 = new loadConL16Node(); 11445 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11446 11447 // inputs for new nodes 11448 m1->add_req(n_region); 11449 m2->add_req(n_region, n_crx, n_mem); 11450 m2->add_prec(m1); 11451 11452 // operands for new nodes 11453 m1->_opnds[0] = op_dst; 11454 m1->_opnds[1] = new immL16Oper(0); 11455 m2->_opnds[0] = op_dst; 11456 m2->_opnds[1] = op_crx; 11457 m2->_opnds[2] = op_mem; 11458 11459 // registers for new nodes 11460 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11461 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11462 11463 // Insert new nodes. 11464 nodes->push(m1); 11465 nodes->push(m2); 11466 %} 11467 %} 11468 11469 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11470 // no match-rule, false predicate 11471 effect(DEF dst, USE crx, USE src); 11472 predicate(false); 11473 11474 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11475 postalloc_expand %{ 11476 // 11477 // replaces 11478 // 11479 // region dst crx src 11480 // \ | | / 11481 // dst=cmovL_bso_reg_conLvalue0 11482 // 11483 // with 11484 // 11485 // region dst 11486 // \ / 11487 // dst=loadConL16(0) 11488 // | 11489 // ^ region dst crx src 11490 // | \ | | / 11491 // dst=cmovL_bso_reg 11492 // 11493 11494 // Create new nodes. 11495 MachNode *m1 = new loadConL16Node(); 11496 MachNode *m2 = new cmovL_bso_regNode(); 11497 11498 // inputs for new nodes 11499 m1->add_req(n_region); 11500 m2->add_req(n_region, n_crx, n_src); 11501 m2->add_prec(m1); 11502 11503 // operands for new nodes 11504 m1->_opnds[0] = op_dst; 11505 m1->_opnds[1] = new immL16Oper(0); 11506 m2->_opnds[0] = op_dst; 11507 m2->_opnds[1] = op_crx; 11508 m2->_opnds[2] = op_src; 11509 11510 // registers for new nodes 11511 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11512 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11513 11514 // Insert new nodes. 11515 nodes->push(m1); 11516 nodes->push(m2); 11517 %} 11518 %} 11519 11520 // Float to Long conversion, NaN is mapped to 0. 11521 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11522 match(Set dst (ConvF2L src)); 11523 predicate(!VM_Version::has_mtfprd()); 11524 ins_cost(DEFAULT_COST); 11525 11526 expand %{ 11527 regF tmpF; 11528 stackSlotL tmpS; 11529 flagsReg crx; 11530 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11531 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11532 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11533 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11534 %} 11535 %} 11536 11537 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11538 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11539 match(Set dst (ConvF2L src)); 11540 predicate(VM_Version::has_mtfprd()); 11541 ins_cost(DEFAULT_COST); 11542 11543 expand %{ 11544 regF tmpF; 11545 flagsReg crx; 11546 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11547 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11548 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11549 %} 11550 %} 11551 11552 instruct convD2LRaw_regD(regD dst, regD src) %{ 11553 // no match-rule, false predicate 11554 effect(DEF dst, USE src); 11555 predicate(false); 11556 11557 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11558 size(4); 11559 ins_encode %{ 11560 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11561 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11562 %} 11563 ins_pipe(pipe_class_default); 11564 %} 11565 11566 // Double to Long conversion, NaN is mapped to 0. 11567 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11568 match(Set dst (ConvD2L src)); 11569 predicate(!VM_Version::has_mtfprd()); 11570 ins_cost(DEFAULT_COST); 11571 11572 expand %{ 11573 regD tmpD; 11574 stackSlotL tmpS; 11575 flagsReg crx; 11576 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11577 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11578 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11579 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11580 %} 11581 %} 11582 11583 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11584 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11585 match(Set dst (ConvD2L src)); 11586 predicate(VM_Version::has_mtfprd()); 11587 ins_cost(DEFAULT_COST); 11588 11589 expand %{ 11590 regD tmpD; 11591 flagsReg crx; 11592 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11593 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11594 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11595 %} 11596 %} 11597 11598 // Convert to Float 11599 11600 // Placed here as needed in expand. 11601 instruct convL2DRaw_regD(regD dst, regD src) %{ 11602 // no match-rule, false predicate 11603 effect(DEF dst, USE src); 11604 predicate(false); 11605 11606 format %{ "FCFID $dst, $src \t// convL2D" %} 11607 size(4); 11608 ins_encode %{ 11609 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11610 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11611 %} 11612 ins_pipe(pipe_class_default); 11613 %} 11614 11615 // Placed here as needed in expand. 11616 instruct convD2F_reg(regF dst, regD src) %{ 11617 match(Set dst (ConvD2F src)); 11618 format %{ "FRSP $dst, $src \t// convD2F" %} 11619 size(4); 11620 ins_encode %{ 11621 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11622 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11623 %} 11624 ins_pipe(pipe_class_default); 11625 %} 11626 11627 // Integer to Float conversion. 11628 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11629 match(Set dst (ConvI2F src)); 11630 predicate(!VM_Version::has_fcfids()); 11631 ins_cost(DEFAULT_COST); 11632 11633 expand %{ 11634 iRegLdst tmpL; 11635 stackSlotL tmpS; 11636 regD tmpD; 11637 regD tmpD2; 11638 convI2L_reg(tmpL, src); // Sign-extension int to long. 11639 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11640 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11641 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11642 convD2F_reg(dst, tmpD2); // Convert double to float. 11643 %} 11644 %} 11645 11646 instruct convL2FRaw_regF(regF dst, regD src) %{ 11647 // no match-rule, false predicate 11648 effect(DEF dst, USE src); 11649 predicate(false); 11650 11651 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11652 size(4); 11653 ins_encode %{ 11654 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11655 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11656 %} 11657 ins_pipe(pipe_class_default); 11658 %} 11659 11660 // Integer to Float conversion. Special version for Power7. 11661 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11662 match(Set dst (ConvI2F src)); 11663 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11664 ins_cost(DEFAULT_COST); 11665 11666 expand %{ 11667 iRegLdst tmpL; 11668 stackSlotL tmpS; 11669 regD tmpD; 11670 convI2L_reg(tmpL, src); // Sign-extension int to long. 11671 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11672 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11673 convL2FRaw_regF(dst, tmpD); // Convert to float. 11674 %} 11675 %} 11676 11677 // Integer to Float conversion. Special version for Power8. 11678 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11679 match(Set dst (ConvI2F src)); 11680 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11681 ins_cost(DEFAULT_COST); 11682 11683 expand %{ 11684 regD tmpD; 11685 moveI2D_reg(tmpD, src); 11686 convL2FRaw_regF(dst, tmpD); // Convert to float. 11687 %} 11688 %} 11689 11690 // L2F to avoid runtime call. 11691 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11692 match(Set dst (ConvL2F src)); 11693 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11694 ins_cost(DEFAULT_COST); 11695 11696 expand %{ 11697 stackSlotL tmpS; 11698 regD tmpD; 11699 regL_to_stkL(tmpS, src); // Store long to stack. 11700 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11701 convL2FRaw_regF(dst, tmpD); // Convert to float. 11702 %} 11703 %} 11704 11705 // L2F to avoid runtime call. Special version for Power8. 11706 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11707 match(Set dst (ConvL2F src)); 11708 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11709 ins_cost(DEFAULT_COST); 11710 11711 expand %{ 11712 regD tmpD; 11713 moveL2D_reg(tmpD, src); 11714 convL2FRaw_regF(dst, tmpD); // Convert to float. 11715 %} 11716 %} 11717 11718 // Moved up as used in expand. 11719 //instruct convD2F_reg(regF dst, regD src) %{%} 11720 11721 // Convert to Double 11722 11723 // Integer to Double conversion. 11724 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11725 match(Set dst (ConvI2D src)); 11726 predicate(!VM_Version::has_mtfprd()); 11727 ins_cost(DEFAULT_COST); 11728 11729 expand %{ 11730 iRegLdst tmpL; 11731 stackSlotL tmpS; 11732 regD tmpD; 11733 convI2L_reg(tmpL, src); // Sign-extension int to long. 11734 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11735 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11736 convL2DRaw_regD(dst, tmpD); // Convert to double. 11737 %} 11738 %} 11739 11740 // Integer to Double conversion. Special version for Power8. 11741 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11742 match(Set dst (ConvI2D src)); 11743 predicate(VM_Version::has_mtfprd()); 11744 ins_cost(DEFAULT_COST); 11745 11746 expand %{ 11747 regD tmpD; 11748 moveI2D_reg(tmpD, src); 11749 convL2DRaw_regD(dst, tmpD); // Convert to double. 11750 %} 11751 %} 11752 11753 // Long to Double conversion 11754 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11755 match(Set dst (ConvL2D src)); 11756 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11757 11758 expand %{ 11759 regD tmpD; 11760 moveL2D_stack_reg(tmpD, src); 11761 convL2DRaw_regD(dst, tmpD); 11762 %} 11763 %} 11764 11765 // Long to Double conversion. Special version for Power8. 11766 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11767 match(Set dst (ConvL2D src)); 11768 predicate(VM_Version::has_mtfprd()); 11769 ins_cost(DEFAULT_COST); 11770 11771 expand %{ 11772 regD tmpD; 11773 moveL2D_reg(tmpD, src); 11774 convL2DRaw_regD(dst, tmpD); // Convert to double. 11775 %} 11776 %} 11777 11778 instruct convF2D_reg(regD dst, regF src) %{ 11779 match(Set dst (ConvF2D src)); 11780 format %{ "FMR $dst, $src \t// float->double" %} 11781 // variable size, 0 or 4 11782 ins_encode %{ 11783 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11784 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11785 %} 11786 ins_pipe(pipe_class_default); 11787 %} 11788 11789 //----------Control Flow Instructions------------------------------------------ 11790 // Compare Instructions 11791 11792 // Compare Integers 11793 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11794 match(Set crx (CmpI src1 src2)); 11795 size(4); 11796 format %{ "CMPW $crx, $src1, $src2" %} 11797 ins_encode %{ 11798 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11799 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11800 %} 11801 ins_pipe(pipe_class_compare); 11802 %} 11803 11804 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11805 match(Set crx (CmpI src1 src2)); 11806 format %{ "CMPWI $crx, $src1, $src2" %} 11807 size(4); 11808 ins_encode %{ 11809 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11810 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11811 %} 11812 ins_pipe(pipe_class_compare); 11813 %} 11814 11815 // (src1 & src2) == 0? 11816 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11817 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11818 // r0 is killed 11819 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11820 size(4); 11821 ins_encode %{ 11822 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11823 __ andi_(R0, $src1$$Register, $src2$$constant); 11824 %} 11825 ins_pipe(pipe_class_compare); 11826 %} 11827 11828 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11829 match(Set crx (CmpL src1 src2)); 11830 format %{ "CMPD $crx, $src1, $src2" %} 11831 size(4); 11832 ins_encode %{ 11833 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11834 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11835 %} 11836 ins_pipe(pipe_class_compare); 11837 %} 11838 11839 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11840 match(Set crx (CmpL src1 src2)); 11841 format %{ "CMPDI $crx, $src1, $src2" %} 11842 size(4); 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11845 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11846 %} 11847 ins_pipe(pipe_class_compare); 11848 %} 11849 11850 // Added CmpUL for LoopPredicate. 11851 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11852 match(Set crx (CmpUL src1 src2)); 11853 format %{ "CMPLD $crx, $src1, $src2" %} 11854 size(4); 11855 ins_encode %{ 11856 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11857 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11858 %} 11859 ins_pipe(pipe_class_compare); 11860 %} 11861 11862 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11863 match(Set crx (CmpUL src1 src2)); 11864 format %{ "CMPLDI $crx, $src1, $src2" %} 11865 size(4); 11866 ins_encode %{ 11867 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11868 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11869 %} 11870 ins_pipe(pipe_class_compare); 11871 %} 11872 11873 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11874 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11875 // r0 is killed 11876 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11877 size(4); 11878 ins_encode %{ 11879 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11880 __ and_(R0, $src1$$Register, $src2$$Register); 11881 %} 11882 ins_pipe(pipe_class_compare); 11883 %} 11884 11885 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11886 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11887 // r0 is killed 11888 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11889 size(4); 11890 ins_encode %{ 11891 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11892 __ andi_(R0, $src1$$Register, $src2$$constant); 11893 %} 11894 ins_pipe(pipe_class_compare); 11895 %} 11896 11897 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11898 // no match-rule, false predicate 11899 effect(DEF dst, USE crx); 11900 predicate(false); 11901 11902 ins_variable_size_depending_on_alignment(true); 11903 11904 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11905 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11906 size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16)); 11907 ins_encode %{ 11908 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11909 Label done; 11910 // li(Rdst, 0); // equal -> 0 11911 __ beq($crx$$CondRegister, done); 11912 __ li($dst$$Register, 1); // greater -> +1 11913 __ bgt($crx$$CondRegister, done); 11914 __ li($dst$$Register, -1); // unordered or less -> -1 11915 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11916 __ bind(done); 11917 %} 11918 ins_pipe(pipe_class_compare); 11919 %} 11920 11921 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11922 // no match-rule, false predicate 11923 effect(DEF dst, USE crx); 11924 predicate(false); 11925 11926 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11927 postalloc_expand %{ 11928 // 11929 // replaces 11930 // 11931 // region crx 11932 // \ | 11933 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11934 // 11935 // with 11936 // 11937 // region 11938 // \ 11939 // dst=loadConI16(0) 11940 // | 11941 // ^ region crx 11942 // | \ | 11943 // dst=cmovI_conIvalueMinus1_conIvalue1 11944 // 11945 11946 // Create new nodes. 11947 MachNode *m1 = new loadConI16Node(); 11948 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11949 11950 // inputs for new nodes 11951 m1->add_req(n_region); 11952 m2->add_req(n_region, n_crx); 11953 m2->add_prec(m1); 11954 11955 // operands for new nodes 11956 m1->_opnds[0] = op_dst; 11957 m1->_opnds[1] = new immI16Oper(0); 11958 m2->_opnds[0] = op_dst; 11959 m2->_opnds[1] = op_crx; 11960 11961 // registers for new nodes 11962 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11963 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11964 11965 // Insert new nodes. 11966 nodes->push(m1); 11967 nodes->push(m2); 11968 %} 11969 %} 11970 11971 // Manifest a CmpL3 result in an integer register. Very painful. 11972 // This is the test to avoid. 11973 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11974 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11975 match(Set dst (CmpL3 src1 src2)); 11976 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11977 11978 expand %{ 11979 flagsReg tmp1; 11980 cmpL_reg_reg(tmp1, src1, src2); 11981 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11982 %} 11983 %} 11984 11985 // Implicit range checks. 11986 // A range check in the ideal world has one of the following shapes: 11987 // - (If le (CmpU length index)), (IfTrue throw exception) 11988 // - (If lt (CmpU index length)), (IfFalse throw exception) 11989 // 11990 // Match range check 'If le (CmpU length index)'. 11991 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11992 match(If cmp (CmpU src_length index)); 11993 effect(USE labl); 11994 predicate(TrapBasedRangeChecks && 11995 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11996 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11997 (Matcher::branches_to_uncommon_trap(_leaf))); 11998 11999 ins_is_TrapBasedCheckNode(true); 12000 12001 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 12002 size(4); 12003 ins_encode %{ 12004 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12005 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 12006 __ trap_range_check_le($src_length$$Register, $index$$constant); 12007 } else { 12008 // Both successors are uncommon traps, probability is 0. 12009 // Node got flipped during fixup flow. 12010 assert($cmp$$cmpcode == 0x9, "must be greater"); 12011 __ trap_range_check_g($src_length$$Register, $index$$constant); 12012 } 12013 %} 12014 ins_pipe(pipe_class_trap); 12015 %} 12016 12017 // Match range check 'If lt (CmpU index length)'. 12018 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 12019 match(If cmp (CmpU src_index src_length)); 12020 effect(USE labl); 12021 predicate(TrapBasedRangeChecks && 12022 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12023 _leaf->as_If()->_prob >= PROB_ALWAYS && 12024 (Matcher::branches_to_uncommon_trap(_leaf))); 12025 12026 ins_is_TrapBasedCheckNode(true); 12027 12028 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12029 size(4); 12030 ins_encode %{ 12031 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12032 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12033 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12034 } else { 12035 // Both successors are uncommon traps, probability is 0. 12036 // Node got flipped during fixup flow. 12037 assert($cmp$$cmpcode == 0x8, "must be less"); 12038 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12039 } 12040 %} 12041 ins_pipe(pipe_class_trap); 12042 %} 12043 12044 // Match range check 'If lt (CmpU index length)'. 12045 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12046 match(If cmp (CmpU src_index length)); 12047 effect(USE labl); 12048 predicate(TrapBasedRangeChecks && 12049 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12050 _leaf->as_If()->_prob >= PROB_ALWAYS && 12051 (Matcher::branches_to_uncommon_trap(_leaf))); 12052 12053 ins_is_TrapBasedCheckNode(true); 12054 12055 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12056 size(4); 12057 ins_encode %{ 12058 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12059 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12060 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12061 } else { 12062 // Both successors are uncommon traps, probability is 0. 12063 // Node got flipped during fixup flow. 12064 assert($cmp$$cmpcode == 0x8, "must be less"); 12065 __ trap_range_check_l($src_index$$Register, $length$$constant); 12066 } 12067 %} 12068 ins_pipe(pipe_class_trap); 12069 %} 12070 12071 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12072 match(Set crx (CmpU src1 src2)); 12073 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12074 size(4); 12075 ins_encode %{ 12076 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12077 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12078 %} 12079 ins_pipe(pipe_class_compare); 12080 %} 12081 12082 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12083 match(Set crx (CmpU src1 src2)); 12084 size(4); 12085 format %{ "CMPLWI $crx, $src1, $src2" %} 12086 ins_encode %{ 12087 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12088 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12089 %} 12090 ins_pipe(pipe_class_compare); 12091 %} 12092 12093 // Implicit zero checks (more implicit null checks). 12094 // No constant pool entries required. 12095 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12096 match(If cmp (CmpN value zero)); 12097 effect(USE labl); 12098 predicate(TrapBasedNullChecks && 12099 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12100 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12101 Matcher::branches_to_uncommon_trap(_leaf)); 12102 ins_cost(1); 12103 12104 ins_is_TrapBasedCheckNode(true); 12105 12106 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12107 size(4); 12108 ins_encode %{ 12109 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12110 if ($cmp$$cmpcode == 0xA) { 12111 __ trap_null_check($value$$Register); 12112 } else { 12113 // Both successors are uncommon traps, probability is 0. 12114 // Node got flipped during fixup flow. 12115 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12116 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12117 } 12118 %} 12119 ins_pipe(pipe_class_trap); 12120 %} 12121 12122 // Compare narrow oops. 12123 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12124 match(Set crx (CmpN src1 src2)); 12125 12126 size(4); 12127 ins_cost(2); 12128 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12129 ins_encode %{ 12130 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12131 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12132 %} 12133 ins_pipe(pipe_class_compare); 12134 %} 12135 12136 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12137 match(Set crx (CmpN src1 src2)); 12138 // Make this more expensive than zeroCheckN_iReg_imm0. 12139 ins_cost(2); 12140 12141 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12142 size(4); 12143 ins_encode %{ 12144 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12145 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12146 %} 12147 ins_pipe(pipe_class_compare); 12148 %} 12149 12150 // Implicit zero checks (more implicit null checks). 12151 // No constant pool entries required. 12152 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12153 match(If cmp (CmpP value zero)); 12154 effect(USE labl); 12155 predicate(TrapBasedNullChecks && 12156 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12157 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12158 Matcher::branches_to_uncommon_trap(_leaf)); 12159 ins_cost(1); // Should not be cheaper than zeroCheckN. 12160 12161 ins_is_TrapBasedCheckNode(true); 12162 12163 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12164 size(4); 12165 ins_encode %{ 12166 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12167 if ($cmp$$cmpcode == 0xA) { 12168 __ trap_null_check($value$$Register); 12169 } else { 12170 // Both successors are uncommon traps, probability is 0. 12171 // Node got flipped during fixup flow. 12172 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12173 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12174 } 12175 %} 12176 ins_pipe(pipe_class_trap); 12177 %} 12178 12179 // Compare Pointers 12180 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12181 match(Set crx (CmpP src1 src2)); 12182 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12183 size(4); 12184 ins_encode %{ 12185 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12186 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12187 %} 12188 ins_pipe(pipe_class_compare); 12189 %} 12190 12191 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12192 match(Set crx (CmpP src1 src2)); 12193 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12194 size(4); 12195 ins_encode %{ 12196 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12197 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12198 %} 12199 ins_pipe(pipe_class_compare); 12200 %} 12201 12202 // Used in postalloc expand. 12203 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12204 // This match rule prevents reordering of node before a safepoint. 12205 // This only makes sense if this instructions is used exclusively 12206 // for the expansion of EncodeP! 12207 match(Set crx (CmpP src1 src2)); 12208 predicate(false); 12209 12210 format %{ "CMPDI $crx, $src1, $src2" %} 12211 size(4); 12212 ins_encode %{ 12213 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12214 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12215 %} 12216 ins_pipe(pipe_class_compare); 12217 %} 12218 12219 //----------Float Compares---------------------------------------------------- 12220 12221 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12222 // Needs matchrule, see cmpDUnordered. 12223 match(Set crx (CmpF src1 src2)); 12224 // no match-rule, false predicate 12225 predicate(false); 12226 12227 format %{ "cmpFUrd $crx, $src1, $src2" %} 12228 size(4); 12229 ins_encode %{ 12230 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12231 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12232 %} 12233 ins_pipe(pipe_class_default); 12234 %} 12235 12236 instruct cmov_bns_less(flagsReg crx) %{ 12237 // no match-rule, false predicate 12238 effect(DEF crx); 12239 predicate(false); 12240 12241 ins_variable_size_depending_on_alignment(true); 12242 12243 format %{ "cmov $crx" %} 12244 // Worst case is branch + move + stop, no stop without scheduler. 12245 size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12)); 12246 ins_encode %{ 12247 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12248 Label done; 12249 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12250 __ li(R0, 0); 12251 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12252 // TODO PPC port __ endgroup_if_needed(_size == 16); 12253 __ bind(done); 12254 %} 12255 ins_pipe(pipe_class_default); 12256 %} 12257 12258 // Compare floating, generate condition code. 12259 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12260 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12261 // 12262 // The following code sequence occurs a lot in mpegaudio: 12263 // 12264 // block BXX: 12265 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12266 // cmpFUrd CCR6, F11, F9 12267 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12268 // cmov CCR6 12269 // 8: instruct branchConSched: 12270 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12271 match(Set crx (CmpF src1 src2)); 12272 ins_cost(DEFAULT_COST+BRANCH_COST); 12273 12274 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12275 postalloc_expand %{ 12276 // 12277 // replaces 12278 // 12279 // region src1 src2 12280 // \ | | 12281 // crx=cmpF_reg_reg 12282 // 12283 // with 12284 // 12285 // region src1 src2 12286 // \ | | 12287 // crx=cmpFUnordered_reg_reg 12288 // | 12289 // ^ region 12290 // | \ 12291 // crx=cmov_bns_less 12292 // 12293 12294 // Create new nodes. 12295 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12296 MachNode *m2 = new cmov_bns_lessNode(); 12297 12298 // inputs for new nodes 12299 m1->add_req(n_region, n_src1, n_src2); 12300 m2->add_req(n_region); 12301 m2->add_prec(m1); 12302 12303 // operands for new nodes 12304 m1->_opnds[0] = op_crx; 12305 m1->_opnds[1] = op_src1; 12306 m1->_opnds[2] = op_src2; 12307 m2->_opnds[0] = op_crx; 12308 12309 // registers for new nodes 12310 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12311 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12312 12313 // Insert new nodes. 12314 nodes->push(m1); 12315 nodes->push(m2); 12316 %} 12317 %} 12318 12319 // Compare float, generate -1,0,1 12320 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12321 match(Set dst (CmpF3 src1 src2)); 12322 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12323 12324 expand %{ 12325 flagsReg tmp1; 12326 cmpFUnordered_reg_reg(tmp1, src1, src2); 12327 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12328 %} 12329 %} 12330 12331 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12332 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12333 // node right before the conditional move using it. 12334 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12335 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12336 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12337 // conditional move was supposed to be spilled. 12338 match(Set crx (CmpD src1 src2)); 12339 // False predicate, shall not be matched. 12340 predicate(false); 12341 12342 format %{ "cmpFUrd $crx, $src1, $src2" %} 12343 size(4); 12344 ins_encode %{ 12345 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12346 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12347 %} 12348 ins_pipe(pipe_class_default); 12349 %} 12350 12351 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12352 match(Set crx (CmpD src1 src2)); 12353 ins_cost(DEFAULT_COST+BRANCH_COST); 12354 12355 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12356 postalloc_expand %{ 12357 // 12358 // replaces 12359 // 12360 // region src1 src2 12361 // \ | | 12362 // crx=cmpD_reg_reg 12363 // 12364 // with 12365 // 12366 // region src1 src2 12367 // \ | | 12368 // crx=cmpDUnordered_reg_reg 12369 // | 12370 // ^ region 12371 // | \ 12372 // crx=cmov_bns_less 12373 // 12374 12375 // create new nodes 12376 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12377 MachNode *m2 = new cmov_bns_lessNode(); 12378 12379 // inputs for new nodes 12380 m1->add_req(n_region, n_src1, n_src2); 12381 m2->add_req(n_region); 12382 m2->add_prec(m1); 12383 12384 // operands for new nodes 12385 m1->_opnds[0] = op_crx; 12386 m1->_opnds[1] = op_src1; 12387 m1->_opnds[2] = op_src2; 12388 m2->_opnds[0] = op_crx; 12389 12390 // registers for new nodes 12391 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12392 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12393 12394 // Insert new nodes. 12395 nodes->push(m1); 12396 nodes->push(m2); 12397 %} 12398 %} 12399 12400 // Compare double, generate -1,0,1 12401 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12402 match(Set dst (CmpD3 src1 src2)); 12403 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12404 12405 expand %{ 12406 flagsReg tmp1; 12407 cmpDUnordered_reg_reg(tmp1, src1, src2); 12408 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12409 %} 12410 %} 12411 12412 // Compare char 12413 instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12414 match(Set dst (Digit src1)); 12415 effect(TEMP src2, TEMP crx); 12416 ins_cost(3 * DEFAULT_COST); 12417 12418 format %{ "LI $src2, 0x3930\n\t" 12419 "CMPRB $crx, 0, $src1, $src2\n\t" 12420 "SETB $dst, $crx" %} 12421 size(12); 12422 ins_encode %{ 12423 // 0x30: 0, 0x39: 9 12424 __ li($src2$$Register, 0x3930); 12425 // compare src1 with ranges 0x30 to 0x39 12426 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12427 __ setb($dst$$Register, $crx$$CondRegister); 12428 %} 12429 ins_pipe(pipe_class_default); 12430 %} 12431 12432 instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12433 match(Set dst (LowerCase src1)); 12434 effect(TEMP src2, TEMP crx); 12435 ins_cost(12 * DEFAULT_COST); 12436 12437 format %{ "LI $src2, 0x7A61\n\t" 12438 "CMPRB $crx, 0, $src1, $src2\n\t" 12439 "BGT $crx, done\n\t" 12440 "LIS $src2, (signed short)0xF6DF\n\t" 12441 "ORI $src2, $src2, 0xFFF8\n\t" 12442 "CMPRB $crx, 1, $src1, $src2\n\t" 12443 "BGT $crx, done\n\t" 12444 "LIS $src2, (signed short)0xAAB5\n\t" 12445 "ORI $src2, $src2, 0xBABA\n\t" 12446 "INSRDI $src2, $src2, 32, 0\n\t" 12447 "CMPEQB $crx, 1, $src1, $src2\n" 12448 "done:\n\t" 12449 "SETB $dst, $crx" %} 12450 12451 size(48); 12452 ins_encode %{ 12453 Label done; 12454 // 0x61: a, 0x7A: z 12455 __ li($src2$$Register, 0x7A61); 12456 // compare src1 with ranges 0x61 to 0x7A 12457 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12458 __ bgt($crx$$CondRegister, done); 12459 12460 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12461 __ lis($src2$$Register, (signed short)0xF6DF); 12462 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12463 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12464 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12465 __ bgt($crx$$CondRegister, done); 12466 12467 // 0xAA: feminine ordinal indicator 12468 // 0xB5: micro sign 12469 // 0xBA: masculine ordinal indicator 12470 __ lis($src2$$Register, (signed short)0xAAB5); 12471 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12472 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12473 // compare src1 with 0xAA, 0xB5, and 0xBA 12474 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12475 12476 __ bind(done); 12477 __ setb($dst$$Register, $crx$$CondRegister); 12478 %} 12479 ins_pipe(pipe_class_default); 12480 %} 12481 12482 instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12483 match(Set dst (UpperCase src1)); 12484 effect(TEMP src2, TEMP crx); 12485 ins_cost(7 * DEFAULT_COST); 12486 12487 format %{ "LI $src2, 0x5A41\n\t" 12488 "CMPRB $crx, 0, $src1, $src2\n\t" 12489 "BGT $crx, done\n\t" 12490 "LIS $src2, (signed short)0xD6C0\n\t" 12491 "ORI $src2, $src2, 0xDED8\n\t" 12492 "CMPRB $crx, 1, $src1, $src2\n" 12493 "done:\n\t" 12494 "SETB $dst, $crx" %} 12495 12496 size(28); 12497 ins_encode %{ 12498 Label done; 12499 // 0x41: A, 0x5A: Z 12500 __ li($src2$$Register, 0x5A41); 12501 // compare src1 with a range 0x41 to 0x5A 12502 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12503 __ bgt($crx$$CondRegister, done); 12504 12505 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12506 __ lis($src2$$Register, (signed short)0xD6C0); 12507 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12508 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12509 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12510 12511 __ bind(done); 12512 __ setb($dst$$Register, $crx$$CondRegister); 12513 %} 12514 ins_pipe(pipe_class_default); 12515 %} 12516 12517 instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12518 match(Set dst (Whitespace src1)); 12519 effect(TEMP src2, TEMP crx); 12520 ins_cost(4 * DEFAULT_COST); 12521 12522 format %{ "LI $src2, 0x0D09\n\t" 12523 "ADDIS $src2, 0x201C\n\t" 12524 "CMPRB $crx, 1, $src1, $src2\n\t" 12525 "SETB $dst, $crx" %} 12526 size(16); 12527 ins_encode %{ 12528 // 0x09 to 0x0D, 0x1C to 0x20 12529 __ li($src2$$Register, 0x0D09); 12530 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12531 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12532 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12533 __ setb($dst$$Register, $crx$$CondRegister); 12534 %} 12535 ins_pipe(pipe_class_default); 12536 %} 12537 12538 //----------Branches--------------------------------------------------------- 12539 // Jump 12540 12541 // Direct Branch. 12542 instruct branch(label labl) %{ 12543 match(Goto); 12544 effect(USE labl); 12545 ins_cost(BRANCH_COST); 12546 12547 format %{ "B $labl" %} 12548 size(4); 12549 ins_encode %{ 12550 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12551 Label d; // dummy 12552 __ bind(d); 12553 Label* p = $labl$$label; 12554 // `p' is `NULL' when this encoding class is used only to 12555 // determine the size of the encoded instruction. 12556 Label& l = (NULL == p)? d : *(p); 12557 __ b(l); 12558 %} 12559 ins_pipe(pipe_class_default); 12560 %} 12561 12562 // Conditional Near Branch 12563 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12564 // Same match rule as `branchConFar'. 12565 match(If cmp crx); 12566 effect(USE lbl); 12567 ins_cost(BRANCH_COST); 12568 12569 // If set to 1 this indicates that the current instruction is a 12570 // short variant of a long branch. This avoids using this 12571 // instruction in first-pass matching. It will then only be used in 12572 // the `Shorten_branches' pass. 12573 ins_short_branch(1); 12574 12575 format %{ "B$cmp $crx, $lbl" %} 12576 size(4); 12577 ins_encode( enc_bc(crx, cmp, lbl) ); 12578 ins_pipe(pipe_class_default); 12579 %} 12580 12581 // This is for cases when the ppc64 `bc' instruction does not 12582 // reach far enough. So we emit a far branch here, which is more 12583 // expensive. 12584 // 12585 // Conditional Far Branch 12586 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12587 // Same match rule as `branchCon'. 12588 match(If cmp crx); 12589 effect(USE crx, USE lbl); 12590 predicate(!false /* TODO: PPC port HB_Schedule*/); 12591 // Higher cost than `branchCon'. 12592 ins_cost(5*BRANCH_COST); 12593 12594 // This is not a short variant of a branch, but the long variant. 12595 ins_short_branch(0); 12596 12597 format %{ "B_FAR$cmp $crx, $lbl" %} 12598 size(8); 12599 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12600 ins_pipe(pipe_class_default); 12601 %} 12602 12603 // Conditional Branch used with Power6 scheduler (can be far or short). 12604 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12605 // Same match rule as `branchCon'. 12606 match(If cmp crx); 12607 effect(USE crx, USE lbl); 12608 predicate(false /* TODO: PPC port HB_Schedule*/); 12609 // Higher cost than `branchCon'. 12610 ins_cost(5*BRANCH_COST); 12611 12612 // Actually size doesn't depend on alignment but on shortening. 12613 ins_variable_size_depending_on_alignment(true); 12614 // long variant. 12615 ins_short_branch(0); 12616 12617 format %{ "B_FAR$cmp $crx, $lbl" %} 12618 size(8); // worst case 12619 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12620 ins_pipe(pipe_class_default); 12621 %} 12622 12623 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12624 match(CountedLoopEnd cmp crx); 12625 effect(USE labl); 12626 ins_cost(BRANCH_COST); 12627 12628 // short variant. 12629 ins_short_branch(1); 12630 12631 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12632 size(4); 12633 ins_encode( enc_bc(crx, cmp, labl) ); 12634 ins_pipe(pipe_class_default); 12635 %} 12636 12637 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12638 match(CountedLoopEnd cmp crx); 12639 effect(USE labl); 12640 predicate(!false /* TODO: PPC port HB_Schedule */); 12641 ins_cost(BRANCH_COST); 12642 12643 // Long variant. 12644 ins_short_branch(0); 12645 12646 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12647 size(8); 12648 ins_encode( enc_bc_far(crx, cmp, labl) ); 12649 ins_pipe(pipe_class_default); 12650 %} 12651 12652 // Conditional Branch used with Power6 scheduler (can be far or short). 12653 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12654 match(CountedLoopEnd cmp crx); 12655 effect(USE labl); 12656 predicate(false /* TODO: PPC port HB_Schedule */); 12657 // Higher cost than `branchCon'. 12658 ins_cost(5*BRANCH_COST); 12659 12660 // Actually size doesn't depend on alignment but on shortening. 12661 ins_variable_size_depending_on_alignment(true); 12662 // Long variant. 12663 ins_short_branch(0); 12664 12665 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12666 size(8); // worst case 12667 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12668 ins_pipe(pipe_class_default); 12669 %} 12670 12671 // ============================================================================ 12672 // Java runtime operations, intrinsics and other complex operations. 12673 12674 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12675 // array for an instance of the superklass. Set a hidden internal cache on a 12676 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12677 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12678 // 12679 // GL TODO: Improve this. 12680 // - result should not be a TEMP 12681 // - Add match rule as on sparc avoiding additional Cmp. 12682 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12683 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12684 match(Set result (PartialSubtypeCheck subklass superklass)); 12685 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12686 ins_cost(DEFAULT_COST*10); 12687 12688 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12689 ins_encode %{ 12690 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12691 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12692 $tmp_klass$$Register, NULL, $result$$Register); 12693 %} 12694 ins_pipe(pipe_class_default); 12695 %} 12696 12697 // inlined locking and unlocking 12698 12699 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12700 match(Set crx (FastLock oop box)); 12701 effect(TEMP tmp1, TEMP tmp2); 12702 predicate(!Compile::current()->use_rtm()); 12703 12704 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12705 ins_encode %{ 12706 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12707 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12708 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12709 UseBiasedLocking && !UseOptoBiasInlining); 12710 // If locking was successfull, crx should indicate 'EQ'. 12711 // The compiler generates a branch to the runtime call to 12712 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12713 %} 12714 ins_pipe(pipe_class_compare); 12715 %} 12716 12717 // Separate version for TM. Use bound register for box to enable USE_KILL. 12718 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12719 match(Set crx (FastLock oop box)); 12720 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12721 predicate(Compile::current()->use_rtm()); 12722 12723 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12724 ins_encode %{ 12725 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12726 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12727 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12728 /*Biased Locking*/ false, 12729 _rtm_counters, _stack_rtm_counters, 12730 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12731 /*TM*/ true, ra_->C->profile_rtm()); 12732 // If locking was successfull, crx should indicate 'EQ'. 12733 // The compiler generates a branch to the runtime call to 12734 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12735 %} 12736 ins_pipe(pipe_class_compare); 12737 %} 12738 12739 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12740 match(Set crx (FastUnlock oop box)); 12741 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12742 predicate(!Compile::current()->use_rtm()); 12743 12744 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12745 ins_encode %{ 12746 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12747 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12748 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12749 UseBiasedLocking && !UseOptoBiasInlining, 12750 false); 12751 // If unlocking was successfull, crx should indicate 'EQ'. 12752 // The compiler generates a branch to the runtime call to 12753 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12754 %} 12755 ins_pipe(pipe_class_compare); 12756 %} 12757 12758 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12759 match(Set crx (FastUnlock oop box)); 12760 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12761 predicate(Compile::current()->use_rtm()); 12762 12763 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12764 ins_encode %{ 12765 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12766 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12767 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12768 /*Biased Locking*/ false, /*TM*/ true); 12769 // If unlocking was successfull, crx should indicate 'EQ'. 12770 // The compiler generates a branch to the runtime call to 12771 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12772 %} 12773 ins_pipe(pipe_class_compare); 12774 %} 12775 12776 // Align address. 12777 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12778 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12779 12780 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12781 size(4); 12782 ins_encode %{ 12783 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12784 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12785 %} 12786 ins_pipe(pipe_class_default); 12787 %} 12788 12789 // Array size computation. 12790 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12791 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12792 12793 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12794 size(4); 12795 ins_encode %{ 12796 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12797 __ subf($dst$$Register, $start$$Register, $end$$Register); 12798 %} 12799 ins_pipe(pipe_class_default); 12800 %} 12801 12802 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12803 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12804 match(Set dummy (ClearArray cnt base)); 12805 effect(USE_KILL base, KILL ctr); 12806 ins_cost(2 * MEMORY_REF_COST); 12807 12808 format %{ "ClearArray $cnt, $base" %} 12809 ins_encode %{ 12810 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12811 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12812 %} 12813 ins_pipe(pipe_class_default); 12814 %} 12815 12816 // Clear-array with constant large array length. 12817 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12818 match(Set dummy (ClearArray cnt base)); 12819 effect(USE_KILL base, TEMP tmp, KILL ctr); 12820 ins_cost(3 * MEMORY_REF_COST); 12821 12822 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12823 ins_encode %{ 12824 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12825 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12826 %} 12827 ins_pipe(pipe_class_default); 12828 %} 12829 12830 // Clear-array with dynamic array length. 12831 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12832 match(Set dummy (ClearArray cnt base)); 12833 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12834 ins_cost(4 * MEMORY_REF_COST); 12835 12836 format %{ "ClearArray $cnt, $base" %} 12837 ins_encode %{ 12838 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12839 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12840 %} 12841 ins_pipe(pipe_class_default); 12842 %} 12843 12844 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12845 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12846 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12847 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12848 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12849 ins_cost(300); 12850 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12851 ins_encode %{ 12852 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12853 __ string_compare($str1$$Register, $str2$$Register, 12854 $cnt1$$Register, $cnt2$$Register, 12855 $tmp$$Register, 12856 $result$$Register, StrIntrinsicNode::LL); 12857 %} 12858 ins_pipe(pipe_class_default); 12859 %} 12860 12861 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12862 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12863 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12864 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12865 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12866 ins_cost(300); 12867 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12868 ins_encode %{ 12869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12870 __ string_compare($str1$$Register, $str2$$Register, 12871 $cnt1$$Register, $cnt2$$Register, 12872 $tmp$$Register, 12873 $result$$Register, StrIntrinsicNode::UU); 12874 %} 12875 ins_pipe(pipe_class_default); 12876 %} 12877 12878 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12879 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12880 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12881 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12882 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12883 ins_cost(300); 12884 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12885 ins_encode %{ 12886 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12887 __ string_compare($str1$$Register, $str2$$Register, 12888 $cnt1$$Register, $cnt2$$Register, 12889 $tmp$$Register, 12890 $result$$Register, StrIntrinsicNode::LU); 12891 %} 12892 ins_pipe(pipe_class_default); 12893 %} 12894 12895 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12896 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12897 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12898 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12899 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12900 ins_cost(300); 12901 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12902 ins_encode %{ 12903 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12904 __ string_compare($str2$$Register, $str1$$Register, 12905 $cnt2$$Register, $cnt1$$Register, 12906 $tmp$$Register, 12907 $result$$Register, StrIntrinsicNode::UL); 12908 %} 12909 ins_pipe(pipe_class_default); 12910 %} 12911 12912 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12913 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12914 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12915 match(Set result (StrEquals (Binary str1 str2) cnt)); 12916 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12917 ins_cost(300); 12918 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12919 ins_encode %{ 12920 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12921 __ array_equals(false, $str1$$Register, $str2$$Register, 12922 $cnt$$Register, $tmp$$Register, 12923 $result$$Register, true /* byte */); 12924 %} 12925 ins_pipe(pipe_class_default); 12926 %} 12927 12928 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12929 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12930 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12931 match(Set result (StrEquals (Binary str1 str2) cnt)); 12932 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12933 ins_cost(300); 12934 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12935 ins_encode %{ 12936 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12937 __ array_equals(false, $str1$$Register, $str2$$Register, 12938 $cnt$$Register, $tmp$$Register, 12939 $result$$Register, false /* byte */); 12940 %} 12941 ins_pipe(pipe_class_default); 12942 %} 12943 12944 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12945 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12946 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12947 match(Set result (AryEq ary1 ary2)); 12948 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12949 ins_cost(300); 12950 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12951 ins_encode %{ 12952 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12953 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12954 $tmp1$$Register, $tmp2$$Register, 12955 $result$$Register, true /* byte */); 12956 %} 12957 ins_pipe(pipe_class_default); 12958 %} 12959 12960 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12961 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12962 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12963 match(Set result (AryEq ary1 ary2)); 12964 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12965 ins_cost(300); 12966 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12967 ins_encode %{ 12968 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12969 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12970 $tmp1$$Register, $tmp2$$Register, 12971 $result$$Register, false /* byte */); 12972 %} 12973 ins_pipe(pipe_class_default); 12974 %} 12975 12976 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12977 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12978 iRegIdst tmp1, iRegIdst tmp2, 12979 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12980 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12981 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12982 // Required for EA: check if it is still a type_array. 12983 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12984 ins_cost(150); 12985 12986 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12987 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12988 12989 ins_encode %{ 12990 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12991 immPOper *needleOper = (immPOper *)$needleImm; 12992 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12993 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12994 jchar chr; 12995 #ifdef VM_LITTLE_ENDIAN 12996 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12997 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12998 #else 12999 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13000 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13001 #endif 13002 __ string_indexof_char($result$$Register, 13003 $haystack$$Register, $haycnt$$Register, 13004 R0, chr, 13005 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13006 %} 13007 ins_pipe(pipe_class_compare); 13008 %} 13009 13010 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13011 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13012 iRegIdst tmp1, iRegIdst tmp2, 13013 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13014 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13015 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13016 // Required for EA: check if it is still a type_array. 13017 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13018 ins_cost(150); 13019 13020 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13021 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13022 13023 ins_encode %{ 13024 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13025 immPOper *needleOper = (immPOper *)$needleImm; 13026 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13027 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13028 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13029 __ string_indexof_char($result$$Register, 13030 $haystack$$Register, $haycnt$$Register, 13031 R0, chr, 13032 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13033 %} 13034 ins_pipe(pipe_class_compare); 13035 %} 13036 13037 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13038 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13039 iRegIdst tmp1, iRegIdst tmp2, 13040 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13041 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13042 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13043 // Required for EA: check if it is still a type_array. 13044 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13045 ins_cost(150); 13046 13047 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13048 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13049 13050 ins_encode %{ 13051 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13052 immPOper *needleOper = (immPOper *)$needleImm; 13053 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13054 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13055 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13056 __ string_indexof_char($result$$Register, 13057 $haystack$$Register, $haycnt$$Register, 13058 R0, chr, 13059 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13060 %} 13061 ins_pipe(pipe_class_compare); 13062 %} 13063 13064 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13065 rscratch2RegP needle, immI_1 needlecntImm, 13066 iRegIdst tmp1, iRegIdst tmp2, 13067 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13068 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13069 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13070 // Required for EA: check if it is still a type_array. 13071 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13072 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13073 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13074 ins_cost(180); 13075 13076 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13077 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13078 ins_encode %{ 13079 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13080 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13081 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13082 guarantee(needle_values, "sanity"); 13083 jchar chr; 13084 #ifdef VM_LITTLE_ENDIAN 13085 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13086 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13087 #else 13088 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13089 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13090 #endif 13091 __ string_indexof_char($result$$Register, 13092 $haystack$$Register, $haycnt$$Register, 13093 R0, chr, 13094 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13095 %} 13096 ins_pipe(pipe_class_compare); 13097 %} 13098 13099 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13100 rscratch2RegP needle, immI_1 needlecntImm, 13101 iRegIdst tmp1, iRegIdst tmp2, 13102 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13103 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13104 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13105 // Required for EA: check if it is still a type_array. 13106 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13107 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13108 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13109 ins_cost(180); 13110 13111 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13112 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13113 ins_encode %{ 13114 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13115 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13116 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13117 guarantee(needle_values, "sanity"); 13118 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13119 __ string_indexof_char($result$$Register, 13120 $haystack$$Register, $haycnt$$Register, 13121 R0, chr, 13122 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13123 %} 13124 ins_pipe(pipe_class_compare); 13125 %} 13126 13127 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13128 rscratch2RegP needle, immI_1 needlecntImm, 13129 iRegIdst tmp1, iRegIdst tmp2, 13130 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13131 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13132 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13133 // Required for EA: check if it is still a type_array. 13134 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13135 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13136 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13137 ins_cost(180); 13138 13139 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13140 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13141 ins_encode %{ 13142 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13143 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13144 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13145 guarantee(needle_values, "sanity"); 13146 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13147 __ string_indexof_char($result$$Register, 13148 $haystack$$Register, $haycnt$$Register, 13149 R0, chr, 13150 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13151 %} 13152 ins_pipe(pipe_class_compare); 13153 %} 13154 13155 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13156 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13157 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13158 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13159 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13160 ins_cost(180); 13161 13162 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13163 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13164 ins_encode %{ 13165 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13166 __ string_indexof_char($result$$Register, 13167 $haystack$$Register, $haycnt$$Register, 13168 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13169 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13170 %} 13171 ins_pipe(pipe_class_compare); 13172 %} 13173 13174 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13175 iRegPsrc needle, uimmI15 needlecntImm, 13176 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13177 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13178 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13179 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13180 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13181 // Required for EA: check if it is still a type_array. 13182 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13183 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13184 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13185 ins_cost(250); 13186 13187 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13188 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13189 ins_encode %{ 13190 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13191 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13192 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13193 13194 __ string_indexof($result$$Register, 13195 $haystack$$Register, $haycnt$$Register, 13196 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13197 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13198 %} 13199 ins_pipe(pipe_class_compare); 13200 %} 13201 13202 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13203 iRegPsrc needle, uimmI15 needlecntImm, 13204 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13205 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13206 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13207 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13208 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13209 // Required for EA: check if it is still a type_array. 13210 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13211 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13212 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13213 ins_cost(250); 13214 13215 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13216 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13217 ins_encode %{ 13218 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13219 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13220 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13221 13222 __ string_indexof($result$$Register, 13223 $haystack$$Register, $haycnt$$Register, 13224 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13225 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13226 %} 13227 ins_pipe(pipe_class_compare); 13228 %} 13229 13230 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13231 iRegPsrc needle, uimmI15 needlecntImm, 13232 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13233 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13234 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13235 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13236 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13237 // Required for EA: check if it is still a type_array. 13238 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13239 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13240 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13241 ins_cost(250); 13242 13243 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13244 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13245 ins_encode %{ 13246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13247 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13248 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13249 13250 __ string_indexof($result$$Register, 13251 $haystack$$Register, $haycnt$$Register, 13252 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13253 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13254 %} 13255 ins_pipe(pipe_class_compare); 13256 %} 13257 13258 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13259 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13260 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13261 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13262 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13263 TEMP_DEF result, 13264 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13265 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13266 ins_cost(300); 13267 13268 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13269 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13270 ins_encode %{ 13271 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13272 __ string_indexof($result$$Register, 13273 $haystack$$Register, $haycnt$$Register, 13274 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13275 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13276 %} 13277 ins_pipe(pipe_class_compare); 13278 %} 13279 13280 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13281 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13282 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13283 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13284 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13285 TEMP_DEF result, 13286 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13287 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13288 ins_cost(300); 13289 13290 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13291 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13292 ins_encode %{ 13293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13294 __ string_indexof($result$$Register, 13295 $haystack$$Register, $haycnt$$Register, 13296 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13297 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13298 %} 13299 ins_pipe(pipe_class_compare); 13300 %} 13301 13302 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13303 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13304 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13305 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13306 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13307 TEMP_DEF result, 13308 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13309 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13310 ins_cost(300); 13311 13312 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13313 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13314 ins_encode %{ 13315 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13316 __ string_indexof($result$$Register, 13317 $haystack$$Register, $haycnt$$Register, 13318 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13319 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13320 %} 13321 ins_pipe(pipe_class_compare); 13322 %} 13323 13324 // char[] to byte[] compression 13325 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13326 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13327 match(Set result (StrCompressedCopy src (Binary dst len))); 13328 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13329 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13330 ins_cost(300); 13331 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13332 ins_encode %{ 13333 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13334 Label Lskip, Ldone; 13335 __ li($result$$Register, 0); 13336 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13337 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13338 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13339 __ beq(CCR0, Lskip); 13340 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13341 __ bind(Lskip); 13342 __ mr($result$$Register, $len$$Register); 13343 __ bind(Ldone); 13344 %} 13345 ins_pipe(pipe_class_default); 13346 %} 13347 13348 // byte[] to char[] inflation 13349 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13350 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13351 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13352 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13353 ins_cost(300); 13354 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13355 ins_encode %{ 13356 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13357 Label Ldone; 13358 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13359 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13360 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13361 __ beq(CCR0, Ldone); 13362 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13363 __ bind(Ldone); 13364 %} 13365 ins_pipe(pipe_class_default); 13366 %} 13367 13368 // StringCoding.java intrinsics 13369 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13370 regCTR ctr, flagsRegCR0 cr0) 13371 %{ 13372 match(Set result (HasNegatives ary1 len)); 13373 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13374 ins_cost(300); 13375 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13376 ins_encode %{ 13377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13378 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13379 $tmp1$$Register, $tmp2$$Register); 13380 %} 13381 ins_pipe(pipe_class_default); 13382 %} 13383 13384 // encode char[] to byte[] in ISO_8859_1 13385 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13386 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13387 match(Set result (EncodeISOArray src (Binary dst len))); 13388 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13389 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13390 ins_cost(300); 13391 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13392 ins_encode %{ 13393 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13394 Label Lslow, Lfailure1, Lfailure2, Ldone; 13395 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13396 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13397 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13398 __ beq(CCR0, Ldone); 13399 __ bind(Lslow); 13400 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13401 __ li($result$$Register, 0); 13402 __ b(Ldone); 13403 13404 __ bind(Lfailure1); 13405 __ mr($result$$Register, $len$$Register); 13406 __ mfctr($tmp1$$Register); 13407 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13408 __ beq(CCR0, Ldone); 13409 __ b(Lslow); 13410 13411 __ bind(Lfailure2); 13412 __ mfctr($result$$Register); // Remaining characters. 13413 13414 __ bind(Ldone); 13415 __ subf($result$$Register, $result$$Register, $len$$Register); 13416 %} 13417 ins_pipe(pipe_class_default); 13418 %} 13419 13420 13421 //---------- Min/Max Instructions --------------------------------------------- 13422 13423 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13424 match(Set dst (MinI src1 src2)); 13425 ins_cost(DEFAULT_COST*6); 13426 13427 expand %{ 13428 iRegLdst src1s; 13429 iRegLdst src2s; 13430 iRegLdst diff; 13431 iRegLdst sm; 13432 iRegLdst doz; // difference or zero 13433 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13434 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13435 subL_reg_reg(diff, src2s, src1s); 13436 // Need to consider >=33 bit result, therefore we need signmaskL. 13437 signmask64L_regL(sm, diff); 13438 andL_reg_reg(doz, diff, sm); // <=0 13439 addI_regL_regL(dst, doz, src1s); 13440 %} 13441 %} 13442 13443 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13444 match(Set dst (MinI src1 src2)); 13445 effect(KILL cr0); 13446 predicate(VM_Version::has_isel()); 13447 ins_cost(DEFAULT_COST*2); 13448 13449 ins_encode %{ 13450 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13451 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13452 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13453 %} 13454 ins_pipe(pipe_class_default); 13455 %} 13456 13457 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13458 match(Set dst (MaxI src1 src2)); 13459 ins_cost(DEFAULT_COST*6); 13460 13461 expand %{ 13462 iRegLdst src1s; 13463 iRegLdst src2s; 13464 iRegLdst diff; 13465 iRegLdst sm; 13466 iRegLdst doz; // difference or zero 13467 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13468 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13469 subL_reg_reg(diff, src2s, src1s); 13470 // Need to consider >=33 bit result, therefore we need signmaskL. 13471 signmask64L_regL(sm, diff); 13472 andcL_reg_reg(doz, diff, sm); // >=0 13473 addI_regL_regL(dst, doz, src1s); 13474 %} 13475 %} 13476 13477 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13478 match(Set dst (MaxI src1 src2)); 13479 effect(KILL cr0); 13480 predicate(VM_Version::has_isel()); 13481 ins_cost(DEFAULT_COST*2); 13482 13483 ins_encode %{ 13484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13485 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13486 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13487 %} 13488 ins_pipe(pipe_class_default); 13489 %} 13490 13491 //---------- Population Count Instructions ------------------------------------ 13492 13493 // Popcnt for Power7. 13494 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13495 match(Set dst (PopCountI src)); 13496 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13497 ins_cost(DEFAULT_COST); 13498 13499 format %{ "POPCNTW $dst, $src" %} 13500 size(4); 13501 ins_encode %{ 13502 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13503 __ popcntw($dst$$Register, $src$$Register); 13504 %} 13505 ins_pipe(pipe_class_default); 13506 %} 13507 13508 // Popcnt for Power7. 13509 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13510 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13511 match(Set dst (PopCountL src)); 13512 ins_cost(DEFAULT_COST); 13513 13514 format %{ "POPCNTD $dst, $src" %} 13515 size(4); 13516 ins_encode %{ 13517 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13518 __ popcntd($dst$$Register, $src$$Register); 13519 %} 13520 ins_pipe(pipe_class_default); 13521 %} 13522 13523 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13524 match(Set dst (CountLeadingZerosI src)); 13525 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13526 ins_cost(DEFAULT_COST); 13527 13528 format %{ "CNTLZW $dst, $src" %} 13529 size(4); 13530 ins_encode %{ 13531 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13532 __ cntlzw($dst$$Register, $src$$Register); 13533 %} 13534 ins_pipe(pipe_class_default); 13535 %} 13536 13537 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13538 match(Set dst (CountLeadingZerosL src)); 13539 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13540 ins_cost(DEFAULT_COST); 13541 13542 format %{ "CNTLZD $dst, $src" %} 13543 size(4); 13544 ins_encode %{ 13545 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13546 __ cntlzd($dst$$Register, $src$$Register); 13547 %} 13548 ins_pipe(pipe_class_default); 13549 %} 13550 13551 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13552 // no match-rule, false predicate 13553 effect(DEF dst, USE src); 13554 predicate(false); 13555 13556 format %{ "CNTLZD $dst, $src" %} 13557 size(4); 13558 ins_encode %{ 13559 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13560 __ cntlzd($dst$$Register, $src$$Register); 13561 %} 13562 ins_pipe(pipe_class_default); 13563 %} 13564 13565 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13566 match(Set dst (CountTrailingZerosI src)); 13567 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13568 ins_cost(DEFAULT_COST); 13569 13570 expand %{ 13571 immI16 imm1 %{ (int)-1 %} 13572 immI16 imm2 %{ (int)32 %} 13573 immI_minus1 m1 %{ -1 %} 13574 iRegIdst tmpI1; 13575 iRegIdst tmpI2; 13576 iRegIdst tmpI3; 13577 addI_reg_imm16(tmpI1, src, imm1); 13578 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13579 countLeadingZerosI(tmpI3, tmpI2); 13580 subI_imm16_reg(dst, imm2, tmpI3); 13581 %} 13582 %} 13583 13584 instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13585 match(Set dst (CountTrailingZerosI src)); 13586 predicate(UseCountTrailingZerosInstructionsPPC64); 13587 ins_cost(DEFAULT_COST); 13588 13589 format %{ "CNTTZW $dst, $src" %} 13590 size(4); 13591 ins_encode %{ 13592 __ cnttzw($dst$$Register, $src$$Register); 13593 %} 13594 ins_pipe(pipe_class_default); 13595 %} 13596 13597 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13598 match(Set dst (CountTrailingZerosL src)); 13599 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13600 ins_cost(DEFAULT_COST); 13601 13602 expand %{ 13603 immL16 imm1 %{ (long)-1 %} 13604 immI16 imm2 %{ (int)64 %} 13605 iRegLdst tmpL1; 13606 iRegLdst tmpL2; 13607 iRegIdst tmpL3; 13608 addL_reg_imm16(tmpL1, src, imm1); 13609 andcL_reg_reg(tmpL2, tmpL1, src); 13610 countLeadingZerosL(tmpL3, tmpL2); 13611 subI_imm16_reg(dst, imm2, tmpL3); 13612 %} 13613 %} 13614 13615 instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13616 match(Set dst (CountTrailingZerosL src)); 13617 predicate(UseCountTrailingZerosInstructionsPPC64); 13618 ins_cost(DEFAULT_COST); 13619 13620 format %{ "CNTTZD $dst, $src" %} 13621 size(4); 13622 ins_encode %{ 13623 __ cnttzd($dst$$Register, $src$$Register); 13624 %} 13625 ins_pipe(pipe_class_default); 13626 %} 13627 13628 // Expand nodes for byte_reverse_int. 13629 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13630 effect(DEF dst, USE src, USE pos, USE shift); 13631 predicate(false); 13632 13633 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13634 size(4); 13635 ins_encode %{ 13636 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13637 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13638 %} 13639 ins_pipe(pipe_class_default); 13640 %} 13641 13642 // As insrwi_a, but with USE_DEF. 13643 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13644 effect(USE_DEF dst, USE src, USE pos, USE shift); 13645 predicate(false); 13646 13647 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13648 size(4); 13649 ins_encode %{ 13650 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13651 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13652 %} 13653 ins_pipe(pipe_class_default); 13654 %} 13655 13656 // Just slightly faster than java implementation. 13657 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13658 match(Set dst (ReverseBytesI src)); 13659 ins_cost(7*DEFAULT_COST); 13660 13661 expand %{ 13662 immI16 imm24 %{ (int) 24 %} 13663 immI16 imm16 %{ (int) 16 %} 13664 immI16 imm8 %{ (int) 8 %} 13665 immI16 imm4 %{ (int) 4 %} 13666 immI16 imm0 %{ (int) 0 %} 13667 iRegLdst tmpI1; 13668 iRegLdst tmpI2; 13669 iRegLdst tmpI3; 13670 13671 urShiftI_reg_imm(tmpI1, src, imm24); 13672 insrwi_a(dst, tmpI1, imm24, imm8); 13673 urShiftI_reg_imm(tmpI2, src, imm16); 13674 insrwi(dst, tmpI2, imm8, imm16); 13675 urShiftI_reg_imm(tmpI3, src, imm8); 13676 insrwi(dst, tmpI3, imm8, imm8); 13677 insrwi(dst, src, imm0, imm8); 13678 %} 13679 %} 13680 13681 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13682 match(Set dst (ReverseBytesL src)); 13683 ins_cost(15*DEFAULT_COST); 13684 13685 expand %{ 13686 immI16 imm56 %{ (int) 56 %} 13687 immI16 imm48 %{ (int) 48 %} 13688 immI16 imm40 %{ (int) 40 %} 13689 immI16 imm32 %{ (int) 32 %} 13690 immI16 imm24 %{ (int) 24 %} 13691 immI16 imm16 %{ (int) 16 %} 13692 immI16 imm8 %{ (int) 8 %} 13693 immI16 imm0 %{ (int) 0 %} 13694 iRegLdst tmpL1; 13695 iRegLdst tmpL2; 13696 iRegLdst tmpL3; 13697 iRegLdst tmpL4; 13698 iRegLdst tmpL5; 13699 iRegLdst tmpL6; 13700 13701 // src : |a|b|c|d|e|f|g|h| 13702 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13703 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13704 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13705 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13706 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13707 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13708 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13709 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13710 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13711 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13712 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13713 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13714 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13715 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13716 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13717 %} 13718 %} 13719 13720 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13721 match(Set dst (ReverseBytesUS src)); 13722 ins_cost(2*DEFAULT_COST); 13723 13724 expand %{ 13725 immI16 imm16 %{ (int) 16 %} 13726 immI16 imm8 %{ (int) 8 %} 13727 13728 urShiftI_reg_imm(dst, src, imm8); 13729 insrwi(dst, src, imm16, imm8); 13730 %} 13731 %} 13732 13733 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13734 match(Set dst (ReverseBytesS src)); 13735 ins_cost(3*DEFAULT_COST); 13736 13737 expand %{ 13738 immI16 imm16 %{ (int) 16 %} 13739 immI16 imm8 %{ (int) 8 %} 13740 iRegLdst tmpI1; 13741 13742 urShiftI_reg_imm(tmpI1, src, imm8); 13743 insrwi(tmpI1, src, imm16, imm8); 13744 extsh(dst, tmpI1); 13745 %} 13746 %} 13747 13748 // Load Integer reversed byte order 13749 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13750 match(Set dst (ReverseBytesI (LoadI mem))); 13751 ins_cost(MEMORY_REF_COST); 13752 13753 size(4); 13754 ins_encode %{ 13755 __ lwbrx($dst$$Register, $mem$$Register); 13756 %} 13757 ins_pipe(pipe_class_default); 13758 %} 13759 13760 // Load Long - aligned and reversed 13761 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13762 match(Set dst (ReverseBytesL (LoadL mem))); 13763 predicate(VM_Version::has_ldbrx()); 13764 ins_cost(MEMORY_REF_COST); 13765 13766 size(4); 13767 ins_encode %{ 13768 __ ldbrx($dst$$Register, $mem$$Register); 13769 %} 13770 ins_pipe(pipe_class_default); 13771 %} 13772 13773 // Load unsigned short / char reversed byte order 13774 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13775 match(Set dst (ReverseBytesUS (LoadUS mem))); 13776 ins_cost(MEMORY_REF_COST); 13777 13778 size(4); 13779 ins_encode %{ 13780 __ lhbrx($dst$$Register, $mem$$Register); 13781 %} 13782 ins_pipe(pipe_class_default); 13783 %} 13784 13785 // Load short reversed byte order 13786 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13787 match(Set dst (ReverseBytesS (LoadS mem))); 13788 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13789 13790 size(8); 13791 ins_encode %{ 13792 __ lhbrx($dst$$Register, $mem$$Register); 13793 __ extsh($dst$$Register, $dst$$Register); 13794 %} 13795 ins_pipe(pipe_class_default); 13796 %} 13797 13798 // Store Integer reversed byte order 13799 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13800 match(Set mem (StoreI mem (ReverseBytesI src))); 13801 ins_cost(MEMORY_REF_COST); 13802 13803 size(4); 13804 ins_encode %{ 13805 __ stwbrx($src$$Register, $mem$$Register); 13806 %} 13807 ins_pipe(pipe_class_default); 13808 %} 13809 13810 // Store Long reversed byte order 13811 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13812 match(Set mem (StoreL mem (ReverseBytesL src))); 13813 predicate(VM_Version::has_stdbrx()); 13814 ins_cost(MEMORY_REF_COST); 13815 13816 size(4); 13817 ins_encode %{ 13818 __ stdbrx($src$$Register, $mem$$Register); 13819 %} 13820 ins_pipe(pipe_class_default); 13821 %} 13822 13823 // Store unsigned short / char reversed byte order 13824 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13825 match(Set mem (StoreC mem (ReverseBytesUS src))); 13826 ins_cost(MEMORY_REF_COST); 13827 13828 size(4); 13829 ins_encode %{ 13830 __ sthbrx($src$$Register, $mem$$Register); 13831 %} 13832 ins_pipe(pipe_class_default); 13833 %} 13834 13835 // Store short reversed byte order 13836 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13837 match(Set mem (StoreC mem (ReverseBytesS src))); 13838 ins_cost(MEMORY_REF_COST); 13839 13840 size(4); 13841 ins_encode %{ 13842 __ sthbrx($src$$Register, $mem$$Register); 13843 %} 13844 ins_pipe(pipe_class_default); 13845 %} 13846 13847 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13848 effect(DEF temp1, USE src); 13849 13850 format %{ "MTVSRWZ $temp1, $src \t// Move to 16-byte register" %} 13851 size(4); 13852 ins_encode %{ 13853 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13854 %} 13855 ins_pipe(pipe_class_default); 13856 %} 13857 13858 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13859 effect(DEF dst, USE src, USE imm1); 13860 13861 format %{ "XXSPLTW $dst, $src, $imm1 \t// Splat word" %} 13862 size(4); 13863 ins_encode %{ 13864 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13865 %} 13866 ins_pipe(pipe_class_default); 13867 %} 13868 13869 instruct xscvdpspn_regF(vecX dst, regF src) %{ 13870 effect(DEF dst, USE src); 13871 13872 format %{ "XSCVDPSPN $dst, $src \t// Convert scalar single precision to vector single precision" %} 13873 size(4); 13874 ins_encode %{ 13875 __ xscvdpspn($dst$$VectorSRegister, $src$$FloatRegister->to_vsr()); 13876 %} 13877 ins_pipe(pipe_class_default); 13878 %} 13879 13880 //---------- Replicate Vector Instructions ------------------------------------ 13881 13882 // Insrdi does replicate if src == dst. 13883 instruct repl32(iRegLdst dst) %{ 13884 predicate(false); 13885 effect(USE_DEF dst); 13886 13887 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13888 size(4); 13889 ins_encode %{ 13890 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13891 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13892 %} 13893 ins_pipe(pipe_class_default); 13894 %} 13895 13896 // Insrdi does replicate if src == dst. 13897 instruct repl48(iRegLdst dst) %{ 13898 predicate(false); 13899 effect(USE_DEF dst); 13900 13901 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13902 size(4); 13903 ins_encode %{ 13904 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13905 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13906 %} 13907 ins_pipe(pipe_class_default); 13908 %} 13909 13910 // Insrdi does replicate if src == dst. 13911 instruct repl56(iRegLdst dst) %{ 13912 predicate(false); 13913 effect(USE_DEF dst); 13914 13915 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13916 size(4); 13917 ins_encode %{ 13918 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13919 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13920 %} 13921 ins_pipe(pipe_class_default); 13922 %} 13923 13924 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13925 match(Set dst (ReplicateB src)); 13926 predicate(n->as_Vector()->length() == 8); 13927 expand %{ 13928 moveReg(dst, src); 13929 repl56(dst); 13930 repl48(dst); 13931 repl32(dst); 13932 %} 13933 %} 13934 13935 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13936 match(Set dst (ReplicateB zero)); 13937 predicate(n->as_Vector()->length() == 8); 13938 format %{ "LI $dst, #0 \t// replicate8B" %} 13939 size(4); 13940 ins_encode %{ 13941 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13942 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13943 %} 13944 ins_pipe(pipe_class_default); 13945 %} 13946 13947 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13948 match(Set dst (ReplicateB src)); 13949 predicate(n->as_Vector()->length() == 8); 13950 format %{ "LI $dst, #-1 \t// replicate8B" %} 13951 size(4); 13952 ins_encode %{ 13953 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13954 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13955 %} 13956 ins_pipe(pipe_class_default); 13957 %} 13958 13959 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13960 match(Set dst (ReplicateB src)); 13961 predicate(n->as_Vector()->length() == 16); 13962 13963 expand %{ 13964 iRegLdst tmpL; 13965 vecX tmpV; 13966 immI8 imm1 %{ (int) 1 %} 13967 moveReg(tmpL, src); 13968 repl56(tmpL); 13969 repl48(tmpL); 13970 mtvsrwz(tmpV, tmpL); 13971 xxspltw(dst, tmpV, imm1); 13972 %} 13973 %} 13974 13975 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13976 match(Set dst (ReplicateB zero)); 13977 predicate(n->as_Vector()->length() == 16); 13978 13979 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13980 size(4); 13981 ins_encode %{ 13982 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13983 %} 13984 ins_pipe(pipe_class_default); 13985 %} 13986 13987 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13988 match(Set dst (ReplicateB src)); 13989 predicate(n->as_Vector()->length() == 16); 13990 13991 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13992 size(4); 13993 ins_encode %{ 13994 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13995 %} 13996 ins_pipe(pipe_class_default); 13997 %} 13998 13999 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14000 match(Set dst (ReplicateS src)); 14001 predicate(n->as_Vector()->length() == 4); 14002 expand %{ 14003 moveReg(dst, src); 14004 repl48(dst); 14005 repl32(dst); 14006 %} 14007 %} 14008 14009 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14010 match(Set dst (ReplicateS zero)); 14011 predicate(n->as_Vector()->length() == 4); 14012 format %{ "LI $dst, #0 \t// replicate4C" %} 14013 size(4); 14014 ins_encode %{ 14015 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14016 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14017 %} 14018 ins_pipe(pipe_class_default); 14019 %} 14020 14021 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14022 match(Set dst (ReplicateS src)); 14023 predicate(n->as_Vector()->length() == 4); 14024 format %{ "LI $dst, -1 \t// replicate4C" %} 14025 size(4); 14026 ins_encode %{ 14027 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14028 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14029 %} 14030 ins_pipe(pipe_class_default); 14031 %} 14032 14033 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14034 match(Set dst (ReplicateS src)); 14035 predicate(n->as_Vector()->length() == 8); 14036 14037 expand %{ 14038 iRegLdst tmpL; 14039 vecX tmpV; 14040 immI8 zero %{ (int) 0 %} 14041 moveReg(tmpL, src); 14042 repl48(tmpL); 14043 repl32(tmpL); 14044 mtvsrd(tmpV, tmpL); 14045 xxpermdi(dst, tmpV, tmpV, zero); 14046 %} 14047 %} 14048 14049 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14050 match(Set dst (ReplicateS zero)); 14051 predicate(n->as_Vector()->length() == 8); 14052 14053 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14054 size(4); 14055 ins_encode %{ 14056 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14057 %} 14058 ins_pipe(pipe_class_default); 14059 %} 14060 14061 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14062 match(Set dst (ReplicateS src)); 14063 predicate(n->as_Vector()->length() == 8); 14064 14065 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14066 size(4); 14067 ins_encode %{ 14068 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14069 %} 14070 ins_pipe(pipe_class_default); 14071 %} 14072 14073 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14074 match(Set dst (ReplicateI src)); 14075 predicate(n->as_Vector()->length() == 2); 14076 ins_cost(2 * DEFAULT_COST); 14077 expand %{ 14078 moveReg(dst, src); 14079 repl32(dst); 14080 %} 14081 %} 14082 14083 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14084 match(Set dst (ReplicateI zero)); 14085 predicate(n->as_Vector()->length() == 2); 14086 format %{ "LI $dst, #0 \t// replicate4C" %} 14087 size(4); 14088 ins_encode %{ 14089 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14090 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14091 %} 14092 ins_pipe(pipe_class_default); 14093 %} 14094 14095 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14096 match(Set dst (ReplicateI src)); 14097 predicate(n->as_Vector()->length() == 2); 14098 format %{ "LI $dst, -1 \t// replicate4C" %} 14099 size(4); 14100 ins_encode %{ 14101 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14102 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14103 %} 14104 ins_pipe(pipe_class_default); 14105 %} 14106 14107 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14108 match(Set dst (ReplicateI src)); 14109 predicate(n->as_Vector()->length() == 4); 14110 ins_cost(2 * DEFAULT_COST); 14111 14112 expand %{ 14113 iRegLdst tmpL; 14114 vecX tmpV; 14115 immI8 zero %{ (int) 0 %} 14116 moveReg(tmpL, src); 14117 repl32(tmpL); 14118 mtvsrd(tmpV, tmpL); 14119 xxpermdi(dst, tmpV, tmpV, zero); 14120 %} 14121 %} 14122 14123 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14124 match(Set dst (ReplicateI zero)); 14125 predicate(n->as_Vector()->length() == 4); 14126 14127 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14128 size(4); 14129 ins_encode %{ 14130 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14131 %} 14132 ins_pipe(pipe_class_default); 14133 %} 14134 14135 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14136 match(Set dst (ReplicateI src)); 14137 predicate(n->as_Vector()->length() == 4); 14138 14139 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14140 size(4); 14141 ins_encode %{ 14142 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14143 %} 14144 ins_pipe(pipe_class_default); 14145 %} 14146 14147 // Move float to int register via stack, replicate. 14148 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14149 match(Set dst (ReplicateF src)); 14150 predicate(n->as_Vector()->length() == 2); 14151 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14152 expand %{ 14153 stackSlotL tmpS; 14154 iRegIdst tmpI; 14155 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14156 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14157 moveReg(dst, tmpI); // Move int to long reg. 14158 repl32(dst); // Replicate bitpattern. 14159 %} 14160 %} 14161 14162 // Replicate scalar constant to packed float values in Double register 14163 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14164 match(Set dst (ReplicateF src)); 14165 predicate(n->as_Vector()->length() == 2); 14166 ins_cost(5 * DEFAULT_COST); 14167 14168 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14169 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14170 %} 14171 14172 // Replicate scalar zero constant to packed float values in Double register 14173 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14174 match(Set dst (ReplicateF zero)); 14175 predicate(n->as_Vector()->length() == 2); 14176 14177 format %{ "LI $dst, #0 \t// replicate2F" %} 14178 ins_encode %{ 14179 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14180 __ li($dst$$Register, 0x0); 14181 %} 14182 ins_pipe(pipe_class_default); 14183 %} 14184 14185 14186 //----------Vector Arithmetic Instructions-------------------------------------- 14187 14188 // Vector Addition Instructions 14189 14190 instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ 14191 match(Set dst (AddVB src1 src2)); 14192 predicate(n->as_Vector()->length() == 16); 14193 format %{ "VADDUBM $dst,$src1,$src2\t// add packed16B" %} 14194 size(4); 14195 ins_encode %{ 14196 __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14197 %} 14198 ins_pipe(pipe_class_default); 14199 %} 14200 14201 instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ 14202 match(Set dst (AddVS src1 src2)); 14203 predicate(n->as_Vector()->length() == 8); 14204 format %{ "VADDUHM $dst,$src1,$src2\t// add packed8S" %} 14205 size(4); 14206 ins_encode %{ 14207 __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14208 %} 14209 ins_pipe(pipe_class_default); 14210 %} 14211 14212 instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ 14213 match(Set dst (AddVI src1 src2)); 14214 predicate(n->as_Vector()->length() == 4); 14215 format %{ "VADDUWM $dst,$src1,$src2\t// add packed4I" %} 14216 size(4); 14217 ins_encode %{ 14218 __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14219 %} 14220 ins_pipe(pipe_class_default); 14221 %} 14222 14223 instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ 14224 match(Set dst (AddVF src1 src2)); 14225 predicate(n->as_Vector()->length() == 4); 14226 format %{ "VADDFP $dst,$src1,$src2\t// add packed4F" %} 14227 size(4); 14228 ins_encode %{ 14229 __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14230 %} 14231 ins_pipe(pipe_class_default); 14232 %} 14233 14234 instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ 14235 match(Set dst (AddVL src1 src2)); 14236 predicate(n->as_Vector()->length() == 2); 14237 format %{ "VADDUDM $dst,$src1,$src2\t// add packed2L" %} 14238 size(4); 14239 ins_encode %{ 14240 __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14241 %} 14242 ins_pipe(pipe_class_default); 14243 %} 14244 14245 instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ 14246 match(Set dst (AddVD src1 src2)); 14247 predicate(n->as_Vector()->length() == 2); 14248 format %{ "XVADDDP $dst,$src1,$src2\t// add packed2D" %} 14249 size(4); 14250 ins_encode %{ 14251 __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14252 %} 14253 ins_pipe(pipe_class_default); 14254 %} 14255 14256 // Vector Subtraction Instructions 14257 14258 instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ 14259 match(Set dst (SubVB src1 src2)); 14260 predicate(n->as_Vector()->length() == 16); 14261 format %{ "VSUBUBM $dst,$src1,$src2\t// sub packed16B" %} 14262 size(4); 14263 ins_encode %{ 14264 __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14265 %} 14266 ins_pipe(pipe_class_default); 14267 %} 14268 14269 instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ 14270 match(Set dst (SubVS src1 src2)); 14271 predicate(n->as_Vector()->length() == 8); 14272 format %{ "VSUBUHM $dst,$src1,$src2\t// sub packed8S" %} 14273 size(4); 14274 ins_encode %{ 14275 __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14276 %} 14277 ins_pipe(pipe_class_default); 14278 %} 14279 14280 instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ 14281 match(Set dst (SubVI src1 src2)); 14282 predicate(n->as_Vector()->length() == 4); 14283 format %{ "VSUBUWM $dst,$src1,$src2\t// sub packed4I" %} 14284 size(4); 14285 ins_encode %{ 14286 __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14287 %} 14288 ins_pipe(pipe_class_default); 14289 %} 14290 14291 instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ 14292 match(Set dst (SubVF src1 src2)); 14293 predicate(n->as_Vector()->length() == 4); 14294 format %{ "VSUBFP $dst,$src1,$src2\t// sub packed4F" %} 14295 size(4); 14296 ins_encode %{ 14297 __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14298 %} 14299 ins_pipe(pipe_class_default); 14300 %} 14301 14302 instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ 14303 match(Set dst (SubVL src1 src2)); 14304 predicate(n->as_Vector()->length() == 2); 14305 format %{ "VSUBUDM $dst,$src1,$src2\t// sub packed2L" %} 14306 size(4); 14307 ins_encode %{ 14308 __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14309 %} 14310 ins_pipe(pipe_class_default); 14311 %} 14312 14313 instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ 14314 match(Set dst (SubVD src1 src2)); 14315 predicate(n->as_Vector()->length() == 2); 14316 format %{ "XVSUBDP $dst,$src1,$src2\t// sub packed2D" %} 14317 size(4); 14318 ins_encode %{ 14319 __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14320 %} 14321 ins_pipe(pipe_class_default); 14322 %} 14323 14324 // Vector Multiplication Instructions 14325 14326 instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{ 14327 match(Set dst (MulVS src1 src2)); 14328 predicate(n->as_Vector()->length() == 8); 14329 effect(TEMP tmp); 14330 format %{ "VSPLTISH $tmp,0\t// mul packed8S" %} 14331 format %{ "VMLADDUHM $dst,$src1,$src2\t// mul packed8S" %} 14332 size(8); 14333 ins_encode %{ 14334 __ vspltish($tmp$$VectorSRegister->to_vr(), 0); 14335 __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr()); 14336 %} 14337 ins_pipe(pipe_class_default); 14338 %} 14339 14340 instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ 14341 match(Set dst (MulVI src1 src2)); 14342 predicate(n->as_Vector()->length() == 4); 14343 format %{ "VMULUWM $dst,$src1,$src2\t// mul packed4I" %} 14344 size(4); 14345 ins_encode %{ 14346 __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr()); 14347 %} 14348 ins_pipe(pipe_class_default); 14349 %} 14350 14351 instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ 14352 match(Set dst (MulVF src1 src2)); 14353 predicate(n->as_Vector()->length() == 4); 14354 format %{ "XVMULSP $dst,$src1,$src2\t// mul packed4F" %} 14355 size(4); 14356 ins_encode %{ 14357 __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14358 %} 14359 ins_pipe(pipe_class_default); 14360 %} 14361 14362 instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ 14363 match(Set dst (MulVD src1 src2)); 14364 predicate(n->as_Vector()->length() == 2); 14365 format %{ "XVMULDP $dst,$src1,$src2\t// mul packed2D" %} 14366 size(4); 14367 ins_encode %{ 14368 __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14369 %} 14370 ins_pipe(pipe_class_default); 14371 %} 14372 14373 // Vector Division Instructions 14374 14375 instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ 14376 match(Set dst (DivVF src1 src2)); 14377 predicate(n->as_Vector()->length() == 4); 14378 format %{ "XVDIVSP $dst,$src1,$src2\t// div packed4F" %} 14379 size(4); 14380 ins_encode %{ 14381 __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14382 %} 14383 ins_pipe(pipe_class_default); 14384 %} 14385 14386 instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ 14387 match(Set dst (DivVD src1 src2)); 14388 predicate(n->as_Vector()->length() == 2); 14389 format %{ "XVDIVDP $dst,$src1,$src2\t// div packed2D" %} 14390 size(4); 14391 ins_encode %{ 14392 __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14393 %} 14394 ins_pipe(pipe_class_default); 14395 %} 14396 14397 // Vector Absolute Instructions 14398 14399 instruct vabs4F_reg(vecX dst, vecX src) %{ 14400 match(Set dst (AbsVF src)); 14401 predicate(n->as_Vector()->length() == 4); 14402 format %{ "XVABSSP $dst,$src\t// absolute packed4F" %} 14403 size(4); 14404 ins_encode %{ 14405 __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister); 14406 %} 14407 ins_pipe(pipe_class_default); 14408 %} 14409 14410 instruct vabs2D_reg(vecX dst, vecX src) %{ 14411 match(Set dst (AbsVD src)); 14412 predicate(n->as_Vector()->length() == 2); 14413 format %{ "XVABSDP $dst,$src\t// absolute packed2D" %} 14414 size(4); 14415 ins_encode %{ 14416 __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister); 14417 %} 14418 ins_pipe(pipe_class_default); 14419 %} 14420 14421 // Vector Negate Instructions 14422 14423 instruct vneg4F_reg(vecX dst, vecX src) %{ 14424 match(Set dst (NegVF src)); 14425 predicate(n->as_Vector()->length() == 4); 14426 format %{ "XVNEGSP $dst,$src\t// negate packed4F" %} 14427 size(4); 14428 ins_encode %{ 14429 __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister); 14430 %} 14431 ins_pipe(pipe_class_default); 14432 %} 14433 14434 instruct vneg2D_reg(vecX dst, vecX src) %{ 14435 match(Set dst (NegVD src)); 14436 predicate(n->as_Vector()->length() == 2); 14437 format %{ "XVNEGDP $dst,$src\t// negate packed2D" %} 14438 size(4); 14439 ins_encode %{ 14440 __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister); 14441 %} 14442 ins_pipe(pipe_class_default); 14443 %} 14444 14445 // Vector Square Root Instructions 14446 14447 instruct vsqrt4F_reg(vecX dst, vecX src) %{ 14448 match(Set dst (SqrtVF src)); 14449 predicate(n->as_Vector()->length() == 4); 14450 format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %} 14451 size(4); 14452 ins_encode %{ 14453 __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister); 14454 %} 14455 ins_pipe(pipe_class_default); 14456 %} 14457 14458 instruct vsqrt2D_reg(vecX dst, vecX src) %{ 14459 match(Set dst (SqrtVD src)); 14460 predicate(n->as_Vector()->length() == 2); 14461 format %{ "XVSQRTDP $dst,$src\t// sqrt packed2D" %} 14462 size(4); 14463 ins_encode %{ 14464 __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister); 14465 %} 14466 ins_pipe(pipe_class_default); 14467 %} 14468 14469 // Vector Population Count Instructions 14470 14471 instruct vpopcnt4I_reg(vecX dst, vecX src) %{ 14472 match(Set dst (PopCountVI src)); 14473 predicate(n->as_Vector()->length() == 4); 14474 format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %} 14475 size(4); 14476 ins_encode %{ 14477 __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr()); 14478 %} 14479 ins_pipe(pipe_class_default); 14480 %} 14481 14482 // --------------------------------- FMA -------------------------------------- 14483 // dst + src1 * src2 14484 instruct vfma4F(vecX dst, vecX src1, vecX src2) %{ 14485 match(Set dst (FmaVF dst (Binary src1 src2))); 14486 predicate(n->as_Vector()->length() == 4); 14487 14488 format %{ "XVMADDASP $dst, $src1, $src2" %} 14489 14490 size(4); 14491 ins_encode %{ 14492 __ xvmaddasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14493 %} 14494 ins_pipe(pipe_class_default); 14495 %} 14496 14497 // dst - src1 * src2 14498 instruct vfma4F_neg1(vecX dst, vecX src1, vecX src2) %{ 14499 match(Set dst (FmaVF dst (Binary (NegVF src1) src2))); 14500 match(Set dst (FmaVF dst (Binary src1 (NegVF src2)))); 14501 predicate(n->as_Vector()->length() == 4); 14502 14503 format %{ "XVNMSUBASP $dst, $src1, $src2" %} 14504 14505 size(4); 14506 ins_encode %{ 14507 __ xvnmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14508 %} 14509 ins_pipe(pipe_class_default); 14510 %} 14511 14512 // - dst + src1 * src2 14513 instruct vfma4F_neg2(vecX dst, vecX src1, vecX src2) %{ 14514 match(Set dst (FmaVF (NegVF dst) (Binary src1 src2))); 14515 predicate(n->as_Vector()->length() == 4); 14516 14517 format %{ "XVMSUBASP $dst, $src1, $src2" %} 14518 14519 size(4); 14520 ins_encode %{ 14521 __ xvmsubasp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14522 %} 14523 ins_pipe(pipe_class_default); 14524 %} 14525 14526 // dst + src1 * src2 14527 instruct vfma2D(vecX dst, vecX src1, vecX src2) %{ 14528 match(Set dst (FmaVD dst (Binary src1 src2))); 14529 predicate(n->as_Vector()->length() == 2); 14530 14531 format %{ "XVMADDADP $dst, $src1, $src2" %} 14532 14533 size(4); 14534 ins_encode %{ 14535 __ xvmaddadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14536 %} 14537 ins_pipe(pipe_class_default); 14538 %} 14539 14540 // dst - src1 * src2 14541 instruct vfma2D_neg1(vecX dst, vecX src1, vecX src2) %{ 14542 match(Set dst (FmaVD dst (Binary (NegVD src1) src2))); 14543 match(Set dst (FmaVD dst (Binary src1 (NegVD src2)))); 14544 predicate(n->as_Vector()->length() == 2); 14545 14546 format %{ "XVNMSUBADP $dst, $src1, $src2" %} 14547 14548 size(4); 14549 ins_encode %{ 14550 __ xvnmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14551 %} 14552 ins_pipe(pipe_class_default); 14553 %} 14554 14555 // - dst + src1 * src2 14556 instruct vfma2D_neg2(vecX dst, vecX src1, vecX src2) %{ 14557 match(Set dst (FmaVD (NegVD dst) (Binary src1 src2))); 14558 predicate(n->as_Vector()->length() == 2); 14559 14560 format %{ "XVMSUBADP $dst, $src1, $src2" %} 14561 14562 size(4); 14563 ins_encode %{ 14564 __ xvmsubadp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister); 14565 %} 14566 ins_pipe(pipe_class_default); 14567 %} 14568 14569 //----------Overflow Math Instructions----------------------------------------- 14570 14571 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 14572 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14573 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14574 14575 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14576 match(Set cr0 (OverflowAddL op1 op2)); 14577 14578 format %{ "add_ $op1, $op2\t# overflow check long" %} 14579 ins_encode %{ 14580 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14581 __ li(R0, 0); 14582 __ mtxer(R0); // clear XER.SO 14583 __ addo_(R0, $op1$$Register, $op2$$Register); 14584 %} 14585 ins_pipe(pipe_class_default); 14586 %} 14587 14588 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14589 match(Set cr0 (OverflowSubL op1 op2)); 14590 14591 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14592 ins_encode %{ 14593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14594 __ li(R0, 0); 14595 __ mtxer(R0); // clear XER.SO 14596 __ subfo_(R0, $op2$$Register, $op1$$Register); 14597 %} 14598 ins_pipe(pipe_class_default); 14599 %} 14600 14601 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14602 match(Set cr0 (OverflowSubL zero op2)); 14603 14604 format %{ "nego_ R0, $op2\t# overflow check long" %} 14605 ins_encode %{ 14606 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14607 __ li(R0, 0); 14608 __ mtxer(R0); // clear XER.SO 14609 __ nego_(R0, $op2$$Register); 14610 %} 14611 ins_pipe(pipe_class_default); 14612 %} 14613 14614 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14615 match(Set cr0 (OverflowMulL op1 op2)); 14616 14617 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14618 ins_encode %{ 14619 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14620 __ li(R0, 0); 14621 __ mtxer(R0); // clear XER.SO 14622 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14623 %} 14624 ins_pipe(pipe_class_default); 14625 %} 14626 14627 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14628 match(Set dst (ReplicateF src)); 14629 predicate(n->as_Vector()->length() == 4); 14630 ins_cost(DEFAULT_COST); 14631 expand %{ 14632 vecX tmpV; 14633 immI8 zero %{ (int) 0 %} 14634 14635 xscvdpspn_regF(tmpV, src); 14636 xxspltw(dst, tmpV, zero); 14637 %} 14638 %} 14639 14640 instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14641 match(Set dst (ReplicateF src)); 14642 predicate(n->as_Vector()->length() == 4); 14643 effect(TEMP tmp); 14644 ins_cost(10 * DEFAULT_COST); 14645 14646 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14647 %} 14648 14649 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14650 match(Set dst (ReplicateF zero)); 14651 predicate(n->as_Vector()->length() == 4); 14652 14653 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14654 ins_encode %{ 14655 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14656 %} 14657 ins_pipe(pipe_class_default); 14658 %} 14659 14660 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14661 match(Set dst (ReplicateD src)); 14662 predicate(n->as_Vector()->length() == 2); 14663 14664 format %{ "XXPERMDI $dst, $src, $src, 0 \t// Splat doubleword" %} 14665 size(4); 14666 ins_encode %{ 14667 __ xxpermdi($dst$$VectorSRegister, $src$$FloatRegister->to_vsr(), $src$$FloatRegister->to_vsr(), 0); 14668 %} 14669 ins_pipe(pipe_class_default); 14670 %} 14671 14672 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14673 match(Set dst (ReplicateD zero)); 14674 predicate(n->as_Vector()->length() == 2); 14675 14676 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14677 size(4); 14678 ins_encode %{ 14679 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14680 %} 14681 ins_pipe(pipe_class_default); 14682 %} 14683 14684 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14685 match(Set dst (ReplicateD src)); 14686 predicate(n->as_Vector()->length() == 2); 14687 14688 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14689 size(4); 14690 ins_encode %{ 14691 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14692 %} 14693 ins_pipe(pipe_class_default); 14694 %} 14695 14696 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14697 predicate(false); 14698 effect(DEF dst, USE src); 14699 14700 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register" %} 14701 size(4); 14702 ins_encode %{ 14703 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14704 %} 14705 ins_pipe(pipe_class_default); 14706 %} 14707 14708 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14709 effect(DEF dst, USE src, USE zero); 14710 14711 format %{ "XXSPLATD $dst, $src, $zero \t// Splat doubleword" %} 14712 size(4); 14713 ins_encode %{ 14714 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14715 %} 14716 ins_pipe(pipe_class_default); 14717 %} 14718 14719 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14720 effect(DEF dst, USE src1, USE src2, USE zero); 14721 14722 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Splat doubleword" %} 14723 size(4); 14724 ins_encode %{ 14725 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14726 %} 14727 ins_pipe(pipe_class_default); 14728 %} 14729 14730 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14731 match(Set dst (ReplicateL src)); 14732 predicate(n->as_Vector()->length() == 2); 14733 expand %{ 14734 vecX tmpV; 14735 immI8 zero %{ (int) 0 %} 14736 mtvsrd(tmpV, src); 14737 xxpermdi(dst, tmpV, tmpV, zero); 14738 %} 14739 %} 14740 14741 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14742 match(Set dst (ReplicateL zero)); 14743 predicate(n->as_Vector()->length() == 2); 14744 14745 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14746 size(4); 14747 ins_encode %{ 14748 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14749 %} 14750 ins_pipe(pipe_class_default); 14751 %} 14752 14753 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14754 match(Set dst (ReplicateL src)); 14755 predicate(n->as_Vector()->length() == 2); 14756 14757 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14758 size(4); 14759 ins_encode %{ 14760 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14761 %} 14762 ins_pipe(pipe_class_default); 14763 %} 14764 14765 // ============================================================================ 14766 // Safepoint Instruction 14767 14768 instruct safePoint_poll(iRegPdst poll) %{ 14769 match(SafePoint poll); 14770 14771 // It caused problems to add the effect that r0 is killed, but this 14772 // effect no longer needs to be mentioned, since r0 is not contained 14773 // in a reg_class. 14774 14775 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14776 size(4); 14777 ins_encode( enc_poll(0x0, poll) ); 14778 ins_pipe(pipe_class_default); 14779 %} 14780 14781 // ============================================================================ 14782 // Call Instructions 14783 14784 // Call Java Static Instruction 14785 14786 // Schedulable version of call static node. 14787 instruct CallStaticJavaDirect(method meth) %{ 14788 match(CallStaticJava); 14789 effect(USE meth); 14790 ins_cost(CALL_COST); 14791 14792 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14793 14794 format %{ "CALL,static $meth \t// ==> " %} 14795 size(4); 14796 ins_encode( enc_java_static_call(meth) ); 14797 ins_pipe(pipe_class_call); 14798 %} 14799 14800 // Call Java Dynamic Instruction 14801 14802 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14803 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14804 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14805 // The call destination must still be placed in the constant pool. 14806 instruct CallDynamicJavaDirectSched(method meth) %{ 14807 match(CallDynamicJava); // To get all the data fields we need ... 14808 effect(USE meth); 14809 predicate(false); // ... but never match. 14810 14811 ins_field_load_ic_hi_node(loadConL_hiNode*); 14812 ins_field_load_ic_node(loadConLNode*); 14813 ins_num_consts(1 /* 1 patchable constant: call destination */); 14814 14815 format %{ "BL \t// dynamic $meth ==> " %} 14816 size(4); 14817 ins_encode( enc_java_dynamic_call_sched(meth) ); 14818 ins_pipe(pipe_class_call); 14819 %} 14820 14821 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14822 // We use postalloc expanded calls if we use inline caches 14823 // and do not update method data. 14824 // 14825 // This instruction has two constants: inline cache (IC) and call destination. 14826 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14827 // one constant. 14828 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14829 match(CallDynamicJava); 14830 effect(USE meth); 14831 predicate(UseInlineCaches); 14832 ins_cost(CALL_COST); 14833 14834 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14835 14836 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14837 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14838 %} 14839 14840 // Compound version of call dynamic java 14841 // We use postalloc expanded calls if we use inline caches 14842 // and do not update method data. 14843 instruct CallDynamicJavaDirect(method meth) %{ 14844 match(CallDynamicJava); 14845 effect(USE meth); 14846 predicate(!UseInlineCaches); 14847 ins_cost(CALL_COST); 14848 14849 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14850 ins_num_consts(4); 14851 14852 format %{ "CALL,dynamic $meth \t// ==> " %} 14853 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14854 ins_pipe(pipe_class_call); 14855 %} 14856 14857 // Call Runtime Instruction 14858 14859 instruct CallRuntimeDirect(method meth) %{ 14860 match(CallRuntime); 14861 effect(USE meth); 14862 ins_cost(CALL_COST); 14863 14864 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14865 // env for callee, C-toc. 14866 ins_num_consts(3); 14867 14868 format %{ "CALL,runtime" %} 14869 ins_encode( enc_java_to_runtime_call(meth) ); 14870 ins_pipe(pipe_class_call); 14871 %} 14872 14873 // Call Leaf 14874 14875 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14876 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14877 effect(DEF dst, USE src); 14878 14879 ins_num_consts(1); 14880 14881 format %{ "MTCTR $src" %} 14882 size(4); 14883 ins_encode( enc_leaf_call_mtctr(src) ); 14884 ins_pipe(pipe_class_default); 14885 %} 14886 14887 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14888 instruct CallLeafDirect(method meth) %{ 14889 match(CallLeaf); // To get the data all the data fields we need ... 14890 effect(USE meth); 14891 predicate(false); // but never match. 14892 14893 format %{ "BCTRL \t// leaf call $meth ==> " %} 14894 size(4); 14895 ins_encode %{ 14896 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14897 __ bctrl(); 14898 %} 14899 ins_pipe(pipe_class_call); 14900 %} 14901 14902 // postalloc expand of CallLeafDirect. 14903 // Load adress to call from TOC, then bl to it. 14904 instruct CallLeafDirect_Ex(method meth) %{ 14905 match(CallLeaf); 14906 effect(USE meth); 14907 ins_cost(CALL_COST); 14908 14909 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14910 // env for callee, C-toc. 14911 ins_num_consts(3); 14912 14913 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14914 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14915 %} 14916 14917 // Call runtime without safepoint - same as CallLeaf. 14918 // postalloc expand of CallLeafNoFPDirect. 14919 // Load adress to call from TOC, then bl to it. 14920 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14921 match(CallLeafNoFP); 14922 effect(USE meth); 14923 ins_cost(CALL_COST); 14924 14925 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14926 // env for callee, C-toc. 14927 ins_num_consts(3); 14928 14929 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14930 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14931 %} 14932 14933 // Tail Call; Jump from runtime stub to Java code. 14934 // Also known as an 'interprocedural jump'. 14935 // Target of jump will eventually return to caller. 14936 // TailJump below removes the return address. 14937 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14938 match(TailCall jump_target method_oop); 14939 ins_cost(CALL_COST); 14940 14941 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14942 "BCTR \t// tail call" %} 14943 size(8); 14944 ins_encode %{ 14945 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14946 __ mtctr($jump_target$$Register); 14947 __ bctr(); 14948 %} 14949 ins_pipe(pipe_class_call); 14950 %} 14951 14952 // Return Instruction 14953 instruct Ret() %{ 14954 match(Return); 14955 format %{ "BLR \t// branch to link register" %} 14956 size(4); 14957 ins_encode %{ 14958 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14959 // LR is restored in MachEpilogNode. Just do the RET here. 14960 __ blr(); 14961 %} 14962 ins_pipe(pipe_class_default); 14963 %} 14964 14965 // Tail Jump; remove the return address; jump to target. 14966 // TailCall above leaves the return address around. 14967 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14968 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14969 // "restore" before this instruction (in Epilogue), we need to materialize it 14970 // in %i0. 14971 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14972 match(TailJump jump_target ex_oop); 14973 ins_cost(CALL_COST); 14974 14975 format %{ "LD R4_ARG2 = LR\n\t" 14976 "MTCTR $jump_target\n\t" 14977 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14978 size(12); 14979 ins_encode %{ 14980 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14981 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14982 __ mtctr($jump_target$$Register); 14983 __ bctr(); 14984 %} 14985 ins_pipe(pipe_class_call); 14986 %} 14987 14988 // Create exception oop: created by stack-crawling runtime code. 14989 // Created exception is now available to this handler, and is setup 14990 // just prior to jumping to this handler. No code emitted. 14991 instruct CreateException(rarg1RegP ex_oop) %{ 14992 match(Set ex_oop (CreateEx)); 14993 ins_cost(0); 14994 14995 format %{ " -- \t// exception oop; no code emitted" %} 14996 size(0); 14997 ins_encode( /*empty*/ ); 14998 ins_pipe(pipe_class_default); 14999 %} 15000 15001 // Rethrow exception: The exception oop will come in the first 15002 // argument position. Then JUMP (not call) to the rethrow stub code. 15003 instruct RethrowException() %{ 15004 match(Rethrow); 15005 ins_cost(CALL_COST); 15006 15007 format %{ "Jmp rethrow_stub" %} 15008 ins_encode %{ 15009 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 15010 cbuf.set_insts_mark(); 15011 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 15012 %} 15013 ins_pipe(pipe_class_call); 15014 %} 15015 15016 // Die now. 15017 instruct ShouldNotReachHere() %{ 15018 match(Halt); 15019 ins_cost(CALL_COST); 15020 15021 format %{ "ShouldNotReachHere" %} 15022 size(4); 15023 ins_encode %{ 15024 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 15025 __ trap_should_not_reach_here(); 15026 %} 15027 ins_pipe(pipe_class_default); 15028 %} 15029 15030 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 15031 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 15032 // Get a DEF on threadRegP, no costs, no encoding, use 15033 // 'ins_should_rematerialize(true)' to avoid spilling. 15034 instruct tlsLoadP(threadRegP dst) %{ 15035 match(Set dst (ThreadLocal)); 15036 ins_cost(0); 15037 15038 ins_should_rematerialize(true); 15039 15040 format %{ " -- \t// $dst=Thread::current(), empty" %} 15041 size(0); 15042 ins_encode( /*empty*/ ); 15043 ins_pipe(pipe_class_empty); 15044 %} 15045 15046 //---Some PPC specific nodes--------------------------------------------------- 15047 15048 // Stop a group. 15049 instruct endGroup() %{ 15050 ins_cost(0); 15051 15052 ins_is_nop(true); 15053 15054 format %{ "End Bundle (ori r1, r1, 0)" %} 15055 size(4); 15056 ins_encode %{ 15057 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 15058 __ endgroup(); 15059 %} 15060 ins_pipe(pipe_class_default); 15061 %} 15062 15063 // Nop instructions 15064 15065 instruct fxNop() %{ 15066 ins_cost(0); 15067 15068 ins_is_nop(true); 15069 15070 format %{ "fxNop" %} 15071 size(4); 15072 ins_encode %{ 15073 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15074 __ nop(); 15075 %} 15076 ins_pipe(pipe_class_default); 15077 %} 15078 15079 instruct fpNop0() %{ 15080 ins_cost(0); 15081 15082 ins_is_nop(true); 15083 15084 format %{ "fpNop0" %} 15085 size(4); 15086 ins_encode %{ 15087 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15088 __ fpnop0(); 15089 %} 15090 ins_pipe(pipe_class_default); 15091 %} 15092 15093 instruct fpNop1() %{ 15094 ins_cost(0); 15095 15096 ins_is_nop(true); 15097 15098 format %{ "fpNop1" %} 15099 size(4); 15100 ins_encode %{ 15101 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 15102 __ fpnop1(); 15103 %} 15104 ins_pipe(pipe_class_default); 15105 %} 15106 15107 instruct brNop0() %{ 15108 ins_cost(0); 15109 size(4); 15110 format %{ "brNop0" %} 15111 ins_encode %{ 15112 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15113 __ brnop0(); 15114 %} 15115 ins_is_nop(true); 15116 ins_pipe(pipe_class_default); 15117 %} 15118 15119 instruct brNop1() %{ 15120 ins_cost(0); 15121 15122 ins_is_nop(true); 15123 15124 format %{ "brNop1" %} 15125 size(4); 15126 ins_encode %{ 15127 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15128 __ brnop1(); 15129 %} 15130 ins_pipe(pipe_class_default); 15131 %} 15132 15133 instruct brNop2() %{ 15134 ins_cost(0); 15135 15136 ins_is_nop(true); 15137 15138 format %{ "brNop2" %} 15139 size(4); 15140 ins_encode %{ 15141 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 15142 __ brnop2(); 15143 %} 15144 ins_pipe(pipe_class_default); 15145 %} 15146 15147 //----------PEEPHOLE RULES----------------------------------------------------- 15148 // These must follow all instruction definitions as they use the names 15149 // defined in the instructions definitions. 15150 // 15151 // peepmatch ( root_instr_name [preceeding_instruction]* ); 15152 // 15153 // peepconstraint %{ 15154 // (instruction_number.operand_name relational_op instruction_number.operand_name 15155 // [, ...] ); 15156 // // instruction numbers are zero-based using left to right order in peepmatch 15157 // 15158 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 15159 // // provide an instruction_number.operand_name for each operand that appears 15160 // // in the replacement instruction's match rule 15161 // 15162 // ---------VM FLAGS--------------------------------------------------------- 15163 // 15164 // All peephole optimizations can be turned off using -XX:-OptoPeephole 15165 // 15166 // Each peephole rule is given an identifying number starting with zero and 15167 // increasing by one in the order seen by the parser. An individual peephole 15168 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 15169 // on the command-line. 15170 // 15171 // ---------CURRENT LIMITATIONS---------------------------------------------- 15172 // 15173 // Only match adjacent instructions in same basic block 15174 // Only equality constraints 15175 // Only constraints between operands, not (0.dest_reg == EAX_enc) 15176 // Only one replacement instruction 15177 // 15178 // ---------EXAMPLE---------------------------------------------------------- 15179 // 15180 // // pertinent parts of existing instructions in architecture description 15181 // instruct movI(eRegI dst, eRegI src) %{ 15182 // match(Set dst (CopyI src)); 15183 // %} 15184 // 15185 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 15186 // match(Set dst (AddI dst src)); 15187 // effect(KILL cr); 15188 // %} 15189 // 15190 // // Change (inc mov) to lea 15191 // peephole %{ 15192 // // increment preceeded by register-register move 15193 // peepmatch ( incI_eReg movI ); 15194 // // require that the destination register of the increment 15195 // // match the destination register of the move 15196 // peepconstraint ( 0.dst == 1.dst ); 15197 // // construct a replacement instruction that sets 15198 // // the destination to ( move's source register + one ) 15199 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15200 // %} 15201 // 15202 // Implementation no longer uses movX instructions since 15203 // machine-independent system no longer uses CopyX nodes. 15204 // 15205 // peephole %{ 15206 // peepmatch ( incI_eReg movI ); 15207 // peepconstraint ( 0.dst == 1.dst ); 15208 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15209 // %} 15210 // 15211 // peephole %{ 15212 // peepmatch ( decI_eReg movI ); 15213 // peepconstraint ( 0.dst == 1.dst ); 15214 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15215 // %} 15216 // 15217 // peephole %{ 15218 // peepmatch ( addI_eReg_imm movI ); 15219 // peepconstraint ( 0.dst == 1.dst ); 15220 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 15221 // %} 15222 // 15223 // peephole %{ 15224 // peepmatch ( addP_eReg_imm movP ); 15225 // peepconstraint ( 0.dst == 1.dst ); 15226 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 15227 // %} 15228 15229 // // Change load of spilled value to only a spill 15230 // instruct storeI(memory mem, eRegI src) %{ 15231 // match(Set mem (StoreI mem src)); 15232 // %} 15233 // 15234 // instruct loadI(eRegI dst, memory mem) %{ 15235 // match(Set dst (LoadI mem)); 15236 // %} 15237 // 15238 peephole %{ 15239 peepmatch ( loadI storeI ); 15240 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15241 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 15242 %} 15243 15244 peephole %{ 15245 peepmatch ( loadL storeL ); 15246 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 15247 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 15248 %} 15249 15250 peephole %{ 15251 peepmatch ( loadP storeP ); 15252 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 15253 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 15254 %} 15255 15256 //----------SMARTSPILL RULES--------------------------------------------------- 15257 // These must follow all instruction definitions as they use the names 15258 // defined in the instructions definitions.