1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 VSR32, 912 VSR33, 913 VSR34, 914 VSR35, 915 VSR36, 916 VSR37, 917 VSR38, 918 VSR39, 919 VSR40, 920 VSR41, 921 VSR42, 922 VSR43, 923 VSR44, 924 VSR45, 925 VSR46, 926 VSR47, 927 VSR48, 928 VSR49, 929 VSR50, 930 VSR51 931 // VSR52, // nv! 932 // VSR53, // nv! 933 // VSR54, // nv! 934 // VSR55, // nv! 935 // VSR56, // nv! 936 // VSR57, // nv! 937 // VSR58, // nv! 938 // VSR59, // nv! 939 // VSR60, // nv! 940 // VSR61, // nv! 941 // VSR62, // nv! 942 // VSR63 // nv! 943 ); 944 945 %} 946 947 //----------DEFINITION BLOCK--------------------------------------------------- 948 // Define name --> value mappings to inform the ADLC of an integer valued name 949 // Current support includes integer values in the range [0, 0x7FFFFFFF] 950 // Format: 951 // int_def <name> ( <int_value>, <expression>); 952 // Generated Code in ad_<arch>.hpp 953 // #define <name> (<expression>) 954 // // value == <int_value> 955 // Generated code in ad_<arch>.cpp adlc_verification() 956 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 957 // 958 definitions %{ 959 // The default cost (of an ALU instruction). 960 int_def DEFAULT_COST_LOW ( 30, 30); 961 int_def DEFAULT_COST ( 100, 100); 962 int_def HUGE_COST (1000000, 1000000); 963 964 // Memory refs 965 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 966 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 967 968 // Branches are even more expensive. 969 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 970 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 971 %} 972 973 974 //----------SOURCE BLOCK------------------------------------------------------- 975 // This is a block of C++ code which provides values, functions, and 976 // definitions necessary in the rest of the architecture description. 977 source_hpp %{ 978 // Header information of the source block. 979 // Method declarations/definitions which are used outside 980 // the ad-scope can conveniently be defined here. 981 // 982 // To keep related declarations/definitions/uses close together, 983 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 984 985 // Returns true if Node n is followed by a MemBar node that 986 // will do an acquire. If so, this node must not do the acquire 987 // operation. 988 bool followed_by_acquire(const Node *n); 989 %} 990 991 source %{ 992 993 // Should the Matcher clone shifts on addressing modes, expecting them 994 // to be subsumed into complex addressing expressions or compute them 995 // into registers? 996 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 997 return clone_base_plus_offset_address(m, mstack, address_visited); 998 } 999 1000 void Compile::reshape_address(AddPNode* addp) { 1001 } 1002 1003 // Optimize load-acquire. 1004 // 1005 // Check if acquire is unnecessary due to following operation that does 1006 // acquire anyways. 1007 // Walk the pattern: 1008 // 1009 // n: Load.acq 1010 // | 1011 // MemBarAcquire 1012 // | | 1013 // Proj(ctrl) Proj(mem) 1014 // | | 1015 // MemBarRelease/Volatile 1016 // 1017 bool followed_by_acquire(const Node *load) { 1018 assert(load->is_Load(), "So far implemented only for loads."); 1019 1020 // Find MemBarAcquire. 1021 const Node *mba = NULL; 1022 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1023 const Node *out = load->fast_out(i); 1024 if (out->Opcode() == Op_MemBarAcquire) { 1025 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1026 mba = out; 1027 break; 1028 } 1029 } 1030 if (!mba) return false; 1031 1032 // Find following MemBar node. 1033 // 1034 // The following node must be reachable by control AND memory 1035 // edge to assure no other operations are in between the two nodes. 1036 // 1037 // So first get the Proj node, mem_proj, to use it to iterate forward. 1038 Node *mem_proj = NULL; 1039 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1040 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 1041 assert(mem_proj->is_Proj(), "only projections here"); 1042 ProjNode *proj = mem_proj->as_Proj(); 1043 if (proj->_con == TypeFunc::Memory && 1044 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1045 break; 1046 } 1047 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1048 1049 // Search MemBar behind Proj. If there are other memory operations 1050 // behind the Proj we lost. 1051 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1052 Node *x = mem_proj->fast_out(j); 1053 // Proj might have an edge to a store or load node which precedes the membar. 1054 if (x->is_Mem()) return false; 1055 1056 // On PPC64 release and volatile are implemented by an instruction 1057 // that also has acquire semantics. I.e. there is no need for an 1058 // acquire before these. 1059 int xop = x->Opcode(); 1060 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1061 // Make sure we're not missing Call/Phi/MergeMem by checking 1062 // control edges. The control edge must directly lead back 1063 // to the MemBarAcquire 1064 Node *ctrl_proj = x->in(0); 1065 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1066 return true; 1067 } 1068 } 1069 } 1070 1071 return false; 1072 } 1073 1074 #define __ _masm. 1075 1076 // Tertiary op of a LoadP or StoreP encoding. 1077 #define REGP_OP true 1078 1079 // **************************************************************************** 1080 1081 // REQUIRED FUNCTIONALITY 1082 1083 // !!!!! Special hack to get all type of calls to specify the byte offset 1084 // from the start of the call to the point where the return address 1085 // will point. 1086 1087 // PPC port: Removed use of lazy constant construct. 1088 1089 int MachCallStaticJavaNode::ret_addr_offset() { 1090 // It's only a single branch-and-link instruction. 1091 return 4; 1092 } 1093 1094 int MachCallDynamicJavaNode::ret_addr_offset() { 1095 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1096 // postalloc expanded calls if we use inline caches and do not update method data. 1097 if (UseInlineCaches) 1098 return 4; 1099 1100 int vtable_index = this->_vtable_index; 1101 if (vtable_index < 0) { 1102 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1103 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1104 return 12; 1105 } else { 1106 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1107 return 24; 1108 } 1109 } 1110 1111 int MachCallRuntimeNode::ret_addr_offset() { 1112 #if defined(ABI_ELFv2) 1113 return 28; 1114 #else 1115 return 40; 1116 #endif 1117 } 1118 1119 //============================================================================= 1120 1121 // condition code conversions 1122 1123 static int cc_to_boint(int cc) { 1124 return Assembler::bcondCRbiIs0 | (cc & 8); 1125 } 1126 1127 static int cc_to_inverse_boint(int cc) { 1128 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1129 } 1130 1131 static int cc_to_biint(int cc, int flags_reg) { 1132 return (flags_reg << 2) | (cc & 3); 1133 } 1134 1135 //============================================================================= 1136 1137 // Compute padding required for nodes which need alignment. The padding 1138 // is the number of bytes (not instructions) which will be inserted before 1139 // the instruction. The padding must match the size of a NOP instruction. 1140 1141 // Currently not used on this platform. 1142 1143 //============================================================================= 1144 1145 // Indicate if the safepoint node needs the polling page as an input. 1146 bool SafePointNode::needs_polling_address_input() { 1147 // The address is loaded from thread by a seperate node. 1148 return true; 1149 } 1150 1151 //============================================================================= 1152 1153 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1154 void emit_break(CodeBuffer &cbuf) { 1155 MacroAssembler _masm(&cbuf); 1156 __ illtrap(); 1157 } 1158 1159 #ifndef PRODUCT 1160 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1161 st->print("BREAKPOINT"); 1162 } 1163 #endif 1164 1165 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1166 emit_break(cbuf); 1167 } 1168 1169 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1170 return MachNode::size(ra_); 1171 } 1172 1173 //============================================================================= 1174 1175 void emit_nop(CodeBuffer &cbuf) { 1176 MacroAssembler _masm(&cbuf); 1177 __ nop(); 1178 } 1179 1180 static inline void emit_long(CodeBuffer &cbuf, int value) { 1181 *((int*)(cbuf.insts_end())) = value; 1182 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1183 } 1184 1185 //============================================================================= 1186 1187 %} // interrupt source 1188 1189 source_hpp %{ // Header information of the source block. 1190 1191 //-------------------------------------------------------------- 1192 //---< Used for optimization in Compile::Shorten_branches >--- 1193 //-------------------------------------------------------------- 1194 1195 class CallStubImpl { 1196 1197 public: 1198 1199 // Emit call stub, compiled java to interpreter. 1200 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1201 1202 // Size of call trampoline stub. 1203 // This doesn't need to be accurate to the byte, but it 1204 // must be larger than or equal to the real size of the stub. 1205 static uint size_call_trampoline() { 1206 return MacroAssembler::trampoline_stub_size; 1207 } 1208 1209 // number of relocations needed by a call trampoline stub 1210 static uint reloc_call_trampoline() { 1211 return 5; 1212 } 1213 1214 }; 1215 1216 %} // end source_hpp 1217 1218 source %{ 1219 1220 // Emit a trampoline stub for a call to a target which is too far away. 1221 // 1222 // code sequences: 1223 // 1224 // call-site: 1225 // branch-and-link to <destination> or <trampoline stub> 1226 // 1227 // Related trampoline stub for this call-site in the stub section: 1228 // load the call target from the constant pool 1229 // branch via CTR (LR/link still points to the call-site above) 1230 1231 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1232 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1233 if (stub == NULL) { 1234 ciEnv::current()->record_out_of_memory_failure(); 1235 } 1236 } 1237 1238 //============================================================================= 1239 1240 // Emit an inline branch-and-link call and a related trampoline stub. 1241 // 1242 // code sequences: 1243 // 1244 // call-site: 1245 // branch-and-link to <destination> or <trampoline stub> 1246 // 1247 // Related trampoline stub for this call-site in the stub section: 1248 // load the call target from the constant pool 1249 // branch via CTR (LR/link still points to the call-site above) 1250 // 1251 1252 typedef struct { 1253 int insts_call_instruction_offset; 1254 int ret_addr_offset; 1255 } EmitCallOffsets; 1256 1257 // Emit a branch-and-link instruction that branches to a trampoline. 1258 // - Remember the offset of the branch-and-link instruction. 1259 // - Add a relocation at the branch-and-link instruction. 1260 // - Emit a branch-and-link. 1261 // - Remember the return pc offset. 1262 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1263 EmitCallOffsets offsets = { -1, -1 }; 1264 const int start_offset = __ offset(); 1265 offsets.insts_call_instruction_offset = __ offset(); 1266 1267 // No entry point given, use the current pc. 1268 if (entry_point == NULL) entry_point = __ pc(); 1269 1270 // Put the entry point as a constant into the constant pool. 1271 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1272 if (entry_point_toc_addr == NULL) { 1273 ciEnv::current()->record_out_of_memory_failure(); 1274 return offsets; 1275 } 1276 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1277 1278 // Emit the trampoline stub which will be related to the branch-and-link below. 1279 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1280 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1281 __ relocate(rtype); 1282 1283 // Note: At this point we do not have the address of the trampoline 1284 // stub, and the entry point might be too far away for bl, so __ pc() 1285 // serves as dummy and the bl will be patched later. 1286 __ bl((address) __ pc()); 1287 1288 offsets.ret_addr_offset = __ offset() - start_offset; 1289 1290 return offsets; 1291 } 1292 1293 //============================================================================= 1294 1295 // Factory for creating loadConL* nodes for large/small constant pool. 1296 1297 static inline jlong replicate_immF(float con) { 1298 // Replicate float con 2 times and pack into vector. 1299 int val = *((int*)&con); 1300 jlong lval = val; 1301 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1302 return lval; 1303 } 1304 1305 //============================================================================= 1306 1307 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1308 int Compile::ConstantTable::calculate_table_base_offset() const { 1309 return 0; // absolute addressing, no offset 1310 } 1311 1312 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1313 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1314 iRegPdstOper *op_dst = new iRegPdstOper(); 1315 MachNode *m1 = new loadToc_hiNode(); 1316 MachNode *m2 = new loadToc_loNode(); 1317 1318 m1->add_req(NULL); 1319 m2->add_req(NULL, m1); 1320 m1->_opnds[0] = op_dst; 1321 m2->_opnds[0] = op_dst; 1322 m2->_opnds[1] = op_dst; 1323 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1324 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1325 nodes->push(m1); 1326 nodes->push(m2); 1327 } 1328 1329 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1330 // Is postalloc expanded. 1331 ShouldNotReachHere(); 1332 } 1333 1334 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1335 return 0; 1336 } 1337 1338 #ifndef PRODUCT 1339 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1340 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1341 } 1342 #endif 1343 1344 //============================================================================= 1345 1346 #ifndef PRODUCT 1347 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1348 Compile* C = ra_->C; 1349 const long framesize = C->frame_slots() << LogBytesPerInt; 1350 1351 st->print("PROLOG\n\t"); 1352 if (C->need_stack_bang(framesize)) { 1353 st->print("stack_overflow_check\n\t"); 1354 } 1355 1356 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1357 st->print("save return pc\n\t"); 1358 st->print("push frame %ld\n\t", -framesize); 1359 } 1360 } 1361 #endif 1362 1363 // Macro used instead of the common __ to emulate the pipes of PPC. 1364 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1365 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1366 // still no scheduling of this code is possible, the micro scheduler is aware of the 1367 // code and can update its internal data. The following mechanism is used to achieve this: 1368 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1369 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1370 #if 0 // TODO: PPC port 1371 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1372 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1373 _masm. 1374 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1375 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1376 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1377 C->hb_scheduling()->_pdScheduling->advance_offset 1378 #else 1379 #define ___(op) if (UsePower6SchedulerPPC64) \ 1380 Unimplemented(); \ 1381 _masm. 1382 #define ___stop if (UsePower6SchedulerPPC64) \ 1383 Unimplemented() 1384 #define ___advance if (UsePower6SchedulerPPC64) \ 1385 Unimplemented() 1386 #endif 1387 1388 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1389 Compile* C = ra_->C; 1390 MacroAssembler _masm(&cbuf); 1391 1392 const long framesize = C->frame_size_in_bytes(); 1393 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1394 1395 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1396 1397 const Register return_pc = R20; // Must match return_addr() in frame section. 1398 const Register callers_sp = R21; 1399 const Register push_frame_temp = R22; 1400 const Register toc_temp = R23; 1401 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1402 1403 if (method_is_frameless) { 1404 // Add nop at beginning of all frameless methods to prevent any 1405 // oop instructions from getting overwritten by make_not_entrant 1406 // (patching attempt would fail). 1407 ___(nop) nop(); 1408 } else { 1409 // Get return pc. 1410 ___(mflr) mflr(return_pc); 1411 } 1412 1413 // Calls to C2R adapters often do not accept exceptional returns. 1414 // We require that their callers must bang for them. But be 1415 // careful, because some VM calls (such as call site linkage) can 1416 // use several kilobytes of stack. But the stack safety zone should 1417 // account for that. See bugs 4446381, 4468289, 4497237. 1418 1419 int bangsize = C->bang_size_in_bytes(); 1420 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1421 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1422 // Unfortunately we cannot use the function provided in 1423 // assembler.cpp as we have to emulate the pipes. So I had to 1424 // insert the code of generate_stack_overflow_check(), see 1425 // assembler.cpp for some illuminative comments. 1426 const int page_size = os::vm_page_size(); 1427 int bang_end = JavaThread::stack_shadow_zone_size(); 1428 1429 // This is how far the previous frame's stack banging extended. 1430 const int bang_end_safe = bang_end; 1431 1432 if (bangsize > page_size) { 1433 bang_end += bangsize; 1434 } 1435 1436 int bang_offset = bang_end_safe; 1437 1438 while (bang_offset <= bang_end) { 1439 // Need at least one stack bang at end of shadow zone. 1440 1441 // Again I had to copy code, this time from assembler_ppc.cpp, 1442 // bang_stack_with_offset - see there for comments. 1443 1444 // Stack grows down, caller passes positive offset. 1445 assert(bang_offset > 0, "must bang with positive offset"); 1446 1447 long stdoffset = -bang_offset; 1448 1449 if (Assembler::is_simm(stdoffset, 16)) { 1450 // Signed 16 bit offset, a simple std is ok. 1451 if (UseLoadInstructionsForStackBangingPPC64) { 1452 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1453 } else { 1454 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1455 } 1456 } else if (Assembler::is_simm(stdoffset, 31)) { 1457 // Use largeoffset calculations for addis & ld/std. 1458 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1459 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1460 1461 Register tmp = R11; 1462 ___(addis) addis(tmp, R1_SP, hi); 1463 if (UseLoadInstructionsForStackBangingPPC64) { 1464 ___(ld) ld(R0, lo, tmp); 1465 } else { 1466 ___(std) std(R0, lo, tmp); 1467 } 1468 } else { 1469 ShouldNotReachHere(); 1470 } 1471 1472 bang_offset += page_size; 1473 } 1474 // R11 trashed 1475 } // C->need_stack_bang(framesize) && UseStackBanging 1476 1477 unsigned int bytes = (unsigned int)framesize; 1478 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1479 ciMethod *currMethod = C->method(); 1480 1481 // Optimized version for most common case. 1482 if (UsePower6SchedulerPPC64 && 1483 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1484 !(false /* ConstantsALot TODO: PPC port*/)) { 1485 ___(or) mr(callers_sp, R1_SP); 1486 ___(std) std(return_pc, _abi(lr), R1_SP); 1487 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1488 return; 1489 } 1490 1491 if (!method_is_frameless) { 1492 // Get callers sp. 1493 ___(or) mr(callers_sp, R1_SP); 1494 1495 // Push method's frame, modifies SP. 1496 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1497 // The ABI is already accounted for in 'framesize' via the 1498 // 'out_preserve' area. 1499 Register tmp = push_frame_temp; 1500 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1501 if (Assembler::is_simm(-offset, 16)) { 1502 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1503 } else { 1504 long x = -offset; 1505 // Had to insert load_const(tmp, -offset). 1506 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1507 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1508 ___(rldicr) sldi(tmp, tmp, 32); 1509 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1510 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1511 1512 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1513 } 1514 } 1515 #if 0 // TODO: PPC port 1516 // For testing large constant pools, emit a lot of constants to constant pool. 1517 // "Randomize" const_size. 1518 if (ConstantsALot) { 1519 const int num_consts = const_size(); 1520 for (int i = 0; i < num_consts; i++) { 1521 __ long_constant(0xB0B5B00BBABE); 1522 } 1523 } 1524 #endif 1525 if (!method_is_frameless) { 1526 // Save return pc. 1527 ___(std) std(return_pc, _abi(lr), callers_sp); 1528 } 1529 1530 C->set_frame_complete(cbuf.insts_size()); 1531 } 1532 #undef ___ 1533 #undef ___stop 1534 #undef ___advance 1535 1536 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1537 // Variable size. determine dynamically. 1538 return MachNode::size(ra_); 1539 } 1540 1541 int MachPrologNode::reloc() const { 1542 // Return number of relocatable values contained in this instruction. 1543 return 1; // 1 reloc entry for load_const(toc). 1544 } 1545 1546 //============================================================================= 1547 1548 #ifndef PRODUCT 1549 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1550 Compile* C = ra_->C; 1551 1552 st->print("EPILOG\n\t"); 1553 st->print("restore return pc\n\t"); 1554 st->print("pop frame\n\t"); 1555 1556 if (do_polling() && C->is_method_compilation()) { 1557 st->print("touch polling page\n\t"); 1558 } 1559 } 1560 #endif 1561 1562 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1563 Compile* C = ra_->C; 1564 MacroAssembler _masm(&cbuf); 1565 1566 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1567 assert(framesize >= 0, "negative frame-size?"); 1568 1569 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1570 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1571 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1572 const Register polling_page = R12; 1573 1574 if (!method_is_frameless) { 1575 // Restore return pc relative to callers' sp. 1576 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1577 } 1578 1579 if (method_needs_polling) { 1580 if (LoadPollAddressFromThread) { 1581 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1582 Unimplemented(); 1583 } else { 1584 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1585 } 1586 } 1587 1588 if (!method_is_frameless) { 1589 // Move return pc to LR. 1590 __ mtlr(return_pc); 1591 // Pop frame (fixed frame-size). 1592 __ addi(R1_SP, R1_SP, (int)framesize); 1593 } 1594 1595 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1596 __ reserved_stack_check(return_pc); 1597 } 1598 1599 if (method_needs_polling) { 1600 // We need to mark the code position where the load from the safepoint 1601 // polling page was emitted as relocInfo::poll_return_type here. 1602 __ relocate(relocInfo::poll_return_type); 1603 __ load_from_polling_page(polling_page); 1604 } 1605 } 1606 1607 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1608 // Variable size. Determine dynamically. 1609 return MachNode::size(ra_); 1610 } 1611 1612 int MachEpilogNode::reloc() const { 1613 // Return number of relocatable values contained in this instruction. 1614 return 1; // 1 for load_from_polling_page. 1615 } 1616 1617 const Pipeline * MachEpilogNode::pipeline() const { 1618 return MachNode::pipeline_class(); 1619 } 1620 1621 // This method seems to be obsolete. It is declared in machnode.hpp 1622 // and defined in all *.ad files, but it is never called. Should we 1623 // get rid of it? 1624 int MachEpilogNode::safepoint_offset() const { 1625 assert(do_polling(), "no return for this epilog node"); 1626 return 0; 1627 } 1628 1629 #if 0 // TODO: PPC port 1630 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1631 MacroAssembler _masm(&cbuf); 1632 if (LoadPollAddressFromThread) { 1633 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1634 } else { 1635 _masm.nop(); 1636 } 1637 } 1638 1639 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1640 if (LoadPollAddressFromThread) { 1641 return 4; 1642 } else { 1643 return 4; 1644 } 1645 } 1646 1647 #ifndef PRODUCT 1648 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1649 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1650 } 1651 #endif 1652 1653 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1654 return RSCRATCH1_BITS64_REG_mask(); 1655 } 1656 #endif // PPC port 1657 1658 // ============================================================================= 1659 1660 // Figure out which register class each belongs in: rc_int, rc_float or 1661 // rc_stack. 1662 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1663 1664 static enum RC rc_class(OptoReg::Name reg) { 1665 // Return the register class for the given register. The given register 1666 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1667 // enumeration in adGlobals_ppc.hpp. 1668 1669 if (reg == OptoReg::Bad) return rc_bad; 1670 1671 // We have 64 integer register halves, starting at index 0. 1672 if (reg < 64) return rc_int; 1673 1674 // We have 64 floating-point register halves, starting at index 64. 1675 if (reg < 64+64) return rc_float; 1676 1677 // Between float regs & stack are the flags regs. 1678 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1679 1680 return rc_stack; 1681 } 1682 1683 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1684 bool do_print, Compile* C, outputStream *st) { 1685 1686 assert(opcode == Assembler::LD_OPCODE || 1687 opcode == Assembler::STD_OPCODE || 1688 opcode == Assembler::LWZ_OPCODE || 1689 opcode == Assembler::STW_OPCODE || 1690 opcode == Assembler::LFD_OPCODE || 1691 opcode == Assembler::STFD_OPCODE || 1692 opcode == Assembler::LFS_OPCODE || 1693 opcode == Assembler::STFS_OPCODE, 1694 "opcode not supported"); 1695 1696 if (cbuf) { 1697 int d = 1698 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1699 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1700 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1701 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1702 } 1703 #ifndef PRODUCT 1704 else if (do_print) { 1705 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1706 op_str, 1707 Matcher::regName[reg], 1708 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1709 } 1710 #endif 1711 return 4; // size 1712 } 1713 1714 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1715 Compile* C = ra_->C; 1716 1717 // Get registers to move. 1718 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1719 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1720 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1721 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1722 1723 enum RC src_hi_rc = rc_class(src_hi); 1724 enum RC src_lo_rc = rc_class(src_lo); 1725 enum RC dst_hi_rc = rc_class(dst_hi); 1726 enum RC dst_lo_rc = rc_class(dst_lo); 1727 1728 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1729 if (src_hi != OptoReg::Bad) 1730 assert((src_lo&1)==0 && src_lo+1==src_hi && 1731 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1732 "expected aligned-adjacent pairs"); 1733 // Generate spill code! 1734 int size = 0; 1735 1736 if (src_lo == dst_lo && src_hi == dst_hi) 1737 return size; // Self copy, no move. 1738 1739 // -------------------------------------- 1740 // Memory->Memory Spill. Use R0 to hold the value. 1741 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1742 int src_offset = ra_->reg2offset(src_lo); 1743 int dst_offset = ra_->reg2offset(dst_lo); 1744 if (src_hi != OptoReg::Bad) { 1745 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1746 "expected same type of move for high parts"); 1747 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1748 if (!cbuf && !do_size) st->print("\n\t"); 1749 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1750 } else { 1751 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1752 if (!cbuf && !do_size) st->print("\n\t"); 1753 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1754 } 1755 return size; 1756 } 1757 1758 // -------------------------------------- 1759 // Check for float->int copy; requires a trip through memory. 1760 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1761 Unimplemented(); 1762 } 1763 1764 // -------------------------------------- 1765 // Check for integer reg-reg copy. 1766 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1767 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1768 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1769 size = (Rsrc != Rdst) ? 4 : 0; 1770 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 if (size) { 1774 __ mr(Rdst, Rsrc); 1775 } 1776 } 1777 #ifndef PRODUCT 1778 else if (!do_size) { 1779 if (size) { 1780 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1781 } else { 1782 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1783 } 1784 } 1785 #endif 1786 return size; 1787 } 1788 1789 // Check for integer store. 1790 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1791 int dst_offset = ra_->reg2offset(dst_lo); 1792 if (src_hi != OptoReg::Bad) { 1793 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1794 "expected same type of move for high parts"); 1795 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1796 } else { 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // Check for integer load. 1803 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1804 int src_offset = ra_->reg2offset(src_lo); 1805 if (src_hi != OptoReg::Bad) { 1806 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1807 "expected same type of move for high parts"); 1808 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1809 } else { 1810 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1811 } 1812 return size; 1813 } 1814 1815 // Check for float reg-reg copy. 1816 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1817 if (cbuf) { 1818 MacroAssembler _masm(cbuf); 1819 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1820 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1821 __ fmr(Rdst, Rsrc); 1822 } 1823 #ifndef PRODUCT 1824 else if (!do_size) { 1825 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1826 } 1827 #endif 1828 return 4; 1829 } 1830 1831 // Check for float store. 1832 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1833 int dst_offset = ra_->reg2offset(dst_lo); 1834 if (src_hi != OptoReg::Bad) { 1835 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1836 "expected same type of move for high parts"); 1837 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1838 } else { 1839 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } 1841 return size; 1842 } 1843 1844 // Check for float load. 1845 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1846 int src_offset = ra_->reg2offset(src_lo); 1847 if (src_hi != OptoReg::Bad) { 1848 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1849 "expected same type of move for high parts"); 1850 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1851 } else { 1852 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } 1854 return size; 1855 } 1856 1857 // -------------------------------------------------------------------- 1858 // Check for hi bits still needing moving. Only happens for misaligned 1859 // arguments to native calls. 1860 if (src_hi == dst_hi) 1861 return size; // Self copy; no move. 1862 1863 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1864 ShouldNotReachHere(); // Unimplemented 1865 return 0; 1866 } 1867 1868 #ifndef PRODUCT 1869 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1870 if (!ra_) 1871 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1872 else 1873 implementation(NULL, ra_, false, st); 1874 } 1875 #endif 1876 1877 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1878 implementation(&cbuf, ra_, false, NULL); 1879 } 1880 1881 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1882 return implementation(NULL, ra_, true, NULL); 1883 } 1884 1885 #if 0 // TODO: PPC port 1886 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1887 #ifndef PRODUCT 1888 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1889 #endif 1890 assert(ra_->node_regs_max_index() != 0, ""); 1891 1892 // Get registers to move. 1893 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1894 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1895 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1896 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1897 1898 enum RC src_lo_rc = rc_class(src_lo); 1899 enum RC dst_lo_rc = rc_class(dst_lo); 1900 1901 if (src_lo == dst_lo && src_hi == dst_hi) 1902 return ppc64Opcode_none; // Self copy, no move. 1903 1904 // -------------------------------------- 1905 // Memory->Memory Spill. Use R0 to hold the value. 1906 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1907 return ppc64Opcode_compound; 1908 } 1909 1910 // -------------------------------------- 1911 // Check for float->int copy; requires a trip through memory. 1912 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1913 Unimplemented(); 1914 } 1915 1916 // -------------------------------------- 1917 // Check for integer reg-reg copy. 1918 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1919 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1920 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1921 if (Rsrc == Rdst) { 1922 return ppc64Opcode_none; 1923 } else { 1924 return ppc64Opcode_or; 1925 } 1926 } 1927 1928 // Check for integer store. 1929 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1930 if (src_hi != OptoReg::Bad) { 1931 return ppc64Opcode_std; 1932 } else { 1933 return ppc64Opcode_stw; 1934 } 1935 } 1936 1937 // Check for integer load. 1938 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1939 if (src_hi != OptoReg::Bad) { 1940 return ppc64Opcode_ld; 1941 } else { 1942 return ppc64Opcode_lwz; 1943 } 1944 } 1945 1946 // Check for float reg-reg copy. 1947 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1948 return ppc64Opcode_fmr; 1949 } 1950 1951 // Check for float store. 1952 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1953 if (src_hi != OptoReg::Bad) { 1954 return ppc64Opcode_stfd; 1955 } else { 1956 return ppc64Opcode_stfs; 1957 } 1958 } 1959 1960 // Check for float load. 1961 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1962 if (src_hi != OptoReg::Bad) { 1963 return ppc64Opcode_lfd; 1964 } else { 1965 return ppc64Opcode_lfs; 1966 } 1967 } 1968 1969 // -------------------------------------------------------------------- 1970 // Check for hi bits still needing moving. Only happens for misaligned 1971 // arguments to native calls. 1972 if (src_hi == dst_hi) { 1973 return ppc64Opcode_none; // Self copy; no move. 1974 } 1975 1976 ShouldNotReachHere(); 1977 return ppc64Opcode_undefined; 1978 } 1979 #endif // PPC port 1980 1981 #ifndef PRODUCT 1982 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1983 st->print("NOP \t// %d nops to pad for loops.", _count); 1984 } 1985 #endif 1986 1987 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1988 MacroAssembler _masm(&cbuf); 1989 // _count contains the number of nops needed for padding. 1990 for (int i = 0; i < _count; i++) { 1991 __ nop(); 1992 } 1993 } 1994 1995 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1996 return _count * 4; 1997 } 1998 1999 #ifndef PRODUCT 2000 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2001 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2002 char reg_str[128]; 2003 ra_->dump_register(this, reg_str); 2004 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2005 } 2006 #endif 2007 2008 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2009 MacroAssembler _masm(&cbuf); 2010 2011 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2012 int reg = ra_->get_encode(this); 2013 2014 if (Assembler::is_simm(offset, 16)) { 2015 __ addi(as_Register(reg), R1, offset); 2016 } else { 2017 ShouldNotReachHere(); 2018 } 2019 } 2020 2021 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2022 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2023 return 4; 2024 } 2025 2026 #ifndef PRODUCT 2027 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2028 st->print_cr("---- MachUEPNode ----"); 2029 st->print_cr("..."); 2030 } 2031 #endif 2032 2033 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2034 // This is the unverified entry point. 2035 MacroAssembler _masm(&cbuf); 2036 2037 // Inline_cache contains a klass. 2038 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2039 Register receiver_klass = R12_scratch2; // tmp 2040 2041 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2042 assert(R11_scratch1 == R11, "need prologue scratch register"); 2043 2044 // Check for NULL argument if we don't have implicit null checks. 2045 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2046 if (TrapBasedNullChecks) { 2047 __ trap_null_check(R3_ARG1); 2048 } else { 2049 Label valid; 2050 __ cmpdi(CCR0, R3_ARG1, 0); 2051 __ bne_predict_taken(CCR0, valid); 2052 // We have a null argument, branch to ic_miss_stub. 2053 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2054 relocInfo::runtime_call_type); 2055 __ bind(valid); 2056 } 2057 } 2058 // Assume argument is not NULL, load klass from receiver. 2059 __ load_klass(receiver_klass, R3_ARG1); 2060 2061 if (TrapBasedICMissChecks) { 2062 __ trap_ic_miss_check(receiver_klass, ic_klass); 2063 } else { 2064 Label valid; 2065 __ cmpd(CCR0, receiver_klass, ic_klass); 2066 __ beq_predict_taken(CCR0, valid); 2067 // We have an unexpected klass, branch to ic_miss_stub. 2068 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2069 relocInfo::runtime_call_type); 2070 __ bind(valid); 2071 } 2072 2073 // Argument is valid and klass is as expected, continue. 2074 } 2075 2076 #if 0 // TODO: PPC port 2077 // Optimize UEP code on z (save a load_const() call in main path). 2078 int MachUEPNode::ep_offset() { 2079 return 0; 2080 } 2081 #endif 2082 2083 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2084 // Variable size. Determine dynamically. 2085 return MachNode::size(ra_); 2086 } 2087 2088 //============================================================================= 2089 2090 %} // interrupt source 2091 2092 source_hpp %{ // Header information of the source block. 2093 2094 class HandlerImpl { 2095 2096 public: 2097 2098 static int emit_exception_handler(CodeBuffer &cbuf); 2099 static int emit_deopt_handler(CodeBuffer& cbuf); 2100 2101 static uint size_exception_handler() { 2102 // The exception_handler is a b64_patchable. 2103 return MacroAssembler::b64_patchable_size; 2104 } 2105 2106 static uint size_deopt_handler() { 2107 // The deopt_handler is a bl64_patchable. 2108 return MacroAssembler::bl64_patchable_size; 2109 } 2110 2111 }; 2112 2113 %} // end source_hpp 2114 2115 source %{ 2116 2117 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2118 MacroAssembler _masm(&cbuf); 2119 2120 address base = __ start_a_stub(size_exception_handler()); 2121 if (base == NULL) return 0; // CodeBuffer::expand failed 2122 2123 int offset = __ offset(); 2124 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2125 relocInfo::runtime_call_type); 2126 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2127 __ end_a_stub(); 2128 2129 return offset; 2130 } 2131 2132 // The deopt_handler is like the exception handler, but it calls to 2133 // the deoptimization blob instead of jumping to the exception blob. 2134 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2135 MacroAssembler _masm(&cbuf); 2136 2137 address base = __ start_a_stub(size_deopt_handler()); 2138 if (base == NULL) return 0; // CodeBuffer::expand failed 2139 2140 int offset = __ offset(); 2141 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2142 relocInfo::runtime_call_type); 2143 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2144 __ end_a_stub(); 2145 2146 return offset; 2147 } 2148 2149 //============================================================================= 2150 2151 // Use a frame slots bias for frameless methods if accessing the stack. 2152 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2153 if (as_Register(reg_enc) == R1_SP) { 2154 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2155 } 2156 return 0; 2157 } 2158 2159 const bool Matcher::match_rule_supported(int opcode) { 2160 if (!has_match_rule(opcode)) 2161 return false; 2162 2163 switch (opcode) { 2164 case Op_SqrtD: 2165 return VM_Version::has_fsqrt(); 2166 case Op_CountLeadingZerosI: 2167 case Op_CountLeadingZerosL: 2168 case Op_CountTrailingZerosI: 2169 case Op_CountTrailingZerosL: 2170 if (!UseCountLeadingZerosInstructionsPPC64) 2171 return false; 2172 break; 2173 2174 case Op_PopCountI: 2175 case Op_PopCountL: 2176 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2177 2178 case Op_StrComp: 2179 return SpecialStringCompareTo; 2180 case Op_StrEquals: 2181 return SpecialStringEquals; 2182 case Op_StrIndexOf: 2183 return SpecialStringIndexOf; 2184 case Op_StrIndexOfChar: 2185 return SpecialStringIndexOf; 2186 } 2187 2188 return true; // Per default match rules are supported. 2189 } 2190 2191 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2192 2193 // TODO 2194 // identify extra cases that we might want to provide match rules for 2195 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2196 bool ret_value = match_rule_supported(opcode); 2197 // Add rules here. 2198 2199 return ret_value; // Per default match rules are supported. 2200 } 2201 2202 const bool Matcher::has_predicated_vectors(void) { 2203 return false; 2204 } 2205 2206 const int Matcher::float_pressure(int default_pressure_threshold) { 2207 return default_pressure_threshold; 2208 } 2209 2210 int Matcher::regnum_to_fpu_offset(int regnum) { 2211 // No user for this method? 2212 Unimplemented(); 2213 return 999; 2214 } 2215 2216 const bool Matcher::convL2FSupported(void) { 2217 // fcfids can do the conversion (>= Power7). 2218 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2219 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2220 } 2221 2222 // Vector width in bytes. 2223 const int Matcher::vector_width_in_bytes(BasicType bt) { 2224 if (SuperwordUseVSX) { 2225 assert(MaxVectorSize == 16, ""); 2226 return 16; 2227 } else { 2228 assert(MaxVectorSize == 8, ""); 2229 return 8; 2230 } 2231 } 2232 2233 // Vector ideal reg. 2234 const uint Matcher::vector_ideal_reg(int size) { 2235 if (SuperwordUseVSX) { 2236 assert(MaxVectorSize == 16 && size == 16, ""); 2237 return Op_VecX; 2238 } else { 2239 assert(MaxVectorSize == 8 && size == 8, ""); 2240 return Op_RegL; 2241 } 2242 } 2243 2244 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2245 fatal("vector shift is not supported"); 2246 return Node::NotAMachineReg; 2247 } 2248 2249 // Limits on vector size (number of elements) loaded into vector. 2250 const int Matcher::max_vector_size(const BasicType bt) { 2251 assert(is_java_primitive(bt), "only primitive type vectors"); 2252 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2253 } 2254 2255 const int Matcher::min_vector_size(const BasicType bt) { 2256 return max_vector_size(bt); // Same as max. 2257 } 2258 2259 // PPC doesn't support misaligned vectors store/load. 2260 const bool Matcher::misaligned_vectors_ok() { 2261 return !AlignVector; // can be changed by flag 2262 } 2263 2264 // PPC AES support not yet implemented 2265 const bool Matcher::pass_original_key_for_aes() { 2266 return false; 2267 } 2268 2269 // RETURNS: whether this branch offset is short enough that a short 2270 // branch can be used. 2271 // 2272 // If the platform does not provide any short branch variants, then 2273 // this method should return `false' for offset 0. 2274 // 2275 // `Compile::Fill_buffer' will decide on basis of this information 2276 // whether to do the pass `Compile::Shorten_branches' at all. 2277 // 2278 // And `Compile::Shorten_branches' will decide on basis of this 2279 // information whether to replace particular branch sites by short 2280 // ones. 2281 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2282 // Is the offset within the range of a ppc64 pc relative branch? 2283 bool b; 2284 2285 const int safety_zone = 3 * BytesPerInstWord; 2286 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2287 29 - 16 + 1 + 2); 2288 return b; 2289 } 2290 2291 const bool Matcher::isSimpleConstant64(jlong value) { 2292 // Probably always true, even if a temp register is required. 2293 return true; 2294 } 2295 /* TODO: PPC port 2296 // Make a new machine dependent decode node (with its operands). 2297 MachTypeNode *Matcher::make_decode_node() { 2298 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2299 "This method is only implemented for unscaled cOops mode so far"); 2300 MachTypeNode *decode = new decodeN_unscaledNode(); 2301 decode->set_opnd_array(0, new iRegPdstOper()); 2302 decode->set_opnd_array(1, new iRegNsrcOper()); 2303 return decode; 2304 } 2305 */ 2306 2307 // false => size gets scaled to BytesPerLong, ok. 2308 const bool Matcher::init_array_count_is_in_bytes = false; 2309 2310 // Use conditional move (CMOVL) on Power7. 2311 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2312 2313 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2314 // fsel doesn't accept a condition register as input, so this would be slightly different. 2315 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2316 2317 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2318 const bool Matcher::require_postalloc_expand = true; 2319 2320 // Do we need to mask the count passed to shift instructions or does 2321 // the cpu only look at the lower 5/6 bits anyway? 2322 // PowerPC requires masked shift counts. 2323 const bool Matcher::need_masked_shift_count = true; 2324 2325 // This affects two different things: 2326 // - how Decode nodes are matched 2327 // - how ImplicitNullCheck opportunities are recognized 2328 // If true, the matcher will try to remove all Decodes and match them 2329 // (as operands) into nodes. NullChecks are not prepared to deal with 2330 // Decodes by final_graph_reshaping(). 2331 // If false, final_graph_reshaping() forces the decode behind the Cmp 2332 // for a NullCheck. The matcher matches the Decode node into a register. 2333 // Implicit_null_check optimization moves the Decode along with the 2334 // memory operation back up before the NullCheck. 2335 bool Matcher::narrow_oop_use_complex_address() { 2336 // TODO: PPC port if (MatchDecodeNodes) return true; 2337 return false; 2338 } 2339 2340 bool Matcher::narrow_klass_use_complex_address() { 2341 NOT_LP64(ShouldNotCallThis()); 2342 assert(UseCompressedClassPointers, "only for compressed klass code"); 2343 // TODO: PPC port if (MatchDecodeNodes) return true; 2344 return false; 2345 } 2346 2347 bool Matcher::const_oop_prefer_decode() { 2348 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2349 return Universe::narrow_oop_base() == NULL; 2350 } 2351 2352 bool Matcher::const_klass_prefer_decode() { 2353 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2354 return Universe::narrow_klass_base() == NULL; 2355 } 2356 2357 // Is it better to copy float constants, or load them directly from memory? 2358 // Intel can load a float constant from a direct address, requiring no 2359 // extra registers. Most RISCs will have to materialize an address into a 2360 // register first, so they would do better to copy the constant from stack. 2361 const bool Matcher::rematerialize_float_constants = false; 2362 2363 // If CPU can load and store mis-aligned doubles directly then no fixup is 2364 // needed. Else we split the double into 2 integer pieces and move it 2365 // piece-by-piece. Only happens when passing doubles into C code as the 2366 // Java calling convention forces doubles to be aligned. 2367 const bool Matcher::misaligned_doubles_ok = true; 2368 2369 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2370 Unimplemented(); 2371 } 2372 2373 // Advertise here if the CPU requires explicit rounding operations 2374 // to implement the UseStrictFP mode. 2375 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2376 2377 // Do floats take an entire double register or just half? 2378 // 2379 // A float occupies a ppc64 double register. For the allocator, a 2380 // ppc64 double register appears as a pair of float registers. 2381 bool Matcher::float_in_double() { return true; } 2382 2383 // Do ints take an entire long register or just half? 2384 // The relevant question is how the int is callee-saved: 2385 // the whole long is written but de-opt'ing will have to extract 2386 // the relevant 32 bits. 2387 const bool Matcher::int_in_long = true; 2388 2389 // Constants for c2c and c calling conventions. 2390 2391 const MachRegisterNumbers iarg_reg[8] = { 2392 R3_num, R4_num, R5_num, R6_num, 2393 R7_num, R8_num, R9_num, R10_num 2394 }; 2395 2396 const MachRegisterNumbers farg_reg[13] = { 2397 F1_num, F2_num, F3_num, F4_num, 2398 F5_num, F6_num, F7_num, F8_num, 2399 F9_num, F10_num, F11_num, F12_num, 2400 F13_num 2401 }; 2402 2403 const MachRegisterNumbers vsarg_reg[64] = { 2404 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2405 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2406 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2407 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2408 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2409 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2410 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2411 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2412 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2413 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2414 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2415 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2416 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2417 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2418 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2419 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2420 }; 2421 2422 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2423 2424 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2425 2426 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2427 2428 // Return whether or not this register is ever used as an argument. This 2429 // function is used on startup to build the trampoline stubs in generateOptoStub. 2430 // Registers not mentioned will be killed by the VM call in the trampoline, and 2431 // arguments in those registers not be available to the callee. 2432 bool Matcher::can_be_java_arg(int reg) { 2433 // We return true for all registers contained in iarg_reg[] and 2434 // farg_reg[] and their virtual halves. 2435 // We must include the virtual halves in order to get STDs and LDs 2436 // instead of STWs and LWs in the trampoline stubs. 2437 2438 if ( reg == R3_num || reg == R3_H_num 2439 || reg == R4_num || reg == R4_H_num 2440 || reg == R5_num || reg == R5_H_num 2441 || reg == R6_num || reg == R6_H_num 2442 || reg == R7_num || reg == R7_H_num 2443 || reg == R8_num || reg == R8_H_num 2444 || reg == R9_num || reg == R9_H_num 2445 || reg == R10_num || reg == R10_H_num) 2446 return true; 2447 2448 if ( reg == F1_num || reg == F1_H_num 2449 || reg == F2_num || reg == F2_H_num 2450 || reg == F3_num || reg == F3_H_num 2451 || reg == F4_num || reg == F4_H_num 2452 || reg == F5_num || reg == F5_H_num 2453 || reg == F6_num || reg == F6_H_num 2454 || reg == F7_num || reg == F7_H_num 2455 || reg == F8_num || reg == F8_H_num 2456 || reg == F9_num || reg == F9_H_num 2457 || reg == F10_num || reg == F10_H_num 2458 || reg == F11_num || reg == F11_H_num 2459 || reg == F12_num || reg == F12_H_num 2460 || reg == F13_num || reg == F13_H_num) 2461 return true; 2462 2463 return false; 2464 } 2465 2466 bool Matcher::is_spillable_arg(int reg) { 2467 return can_be_java_arg(reg); 2468 } 2469 2470 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2471 return false; 2472 } 2473 2474 // Register for DIVI projection of divmodI. 2475 RegMask Matcher::divI_proj_mask() { 2476 ShouldNotReachHere(); 2477 return RegMask(); 2478 } 2479 2480 // Register for MODI projection of divmodI. 2481 RegMask Matcher::modI_proj_mask() { 2482 ShouldNotReachHere(); 2483 return RegMask(); 2484 } 2485 2486 // Register for DIVL projection of divmodL. 2487 RegMask Matcher::divL_proj_mask() { 2488 ShouldNotReachHere(); 2489 return RegMask(); 2490 } 2491 2492 // Register for MODL projection of divmodL. 2493 RegMask Matcher::modL_proj_mask() { 2494 ShouldNotReachHere(); 2495 return RegMask(); 2496 } 2497 2498 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2499 return RegMask(); 2500 } 2501 2502 const bool Matcher::convi2l_type_required = true; 2503 2504 %} 2505 2506 //----------ENCODING BLOCK----------------------------------------------------- 2507 // This block specifies the encoding classes used by the compiler to output 2508 // byte streams. Encoding classes are parameterized macros used by 2509 // Machine Instruction Nodes in order to generate the bit encoding of the 2510 // instruction. Operands specify their base encoding interface with the 2511 // interface keyword. There are currently supported four interfaces, 2512 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2513 // operand to generate a function which returns its register number when 2514 // queried. CONST_INTER causes an operand to generate a function which 2515 // returns the value of the constant when queried. MEMORY_INTER causes an 2516 // operand to generate four functions which return the Base Register, the 2517 // Index Register, the Scale Value, and the Offset Value of the operand when 2518 // queried. COND_INTER causes an operand to generate six functions which 2519 // return the encoding code (ie - encoding bits for the instruction) 2520 // associated with each basic boolean condition for a conditional instruction. 2521 // 2522 // Instructions specify two basic values for encoding. Again, a function 2523 // is available to check if the constant displacement is an oop. They use the 2524 // ins_encode keyword to specify their encoding classes (which must be 2525 // a sequence of enc_class names, and their parameters, specified in 2526 // the encoding block), and they use the 2527 // opcode keyword to specify, in order, their primary, secondary, and 2528 // tertiary opcode. Only the opcode sections which a particular instruction 2529 // needs for encoding need to be specified. 2530 encode %{ 2531 enc_class enc_unimplemented %{ 2532 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2533 MacroAssembler _masm(&cbuf); 2534 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2535 %} 2536 2537 enc_class enc_untested %{ 2538 #ifdef ASSERT 2539 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2540 MacroAssembler _masm(&cbuf); 2541 __ untested("Untested mach node encoding in AD file."); 2542 #else 2543 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2544 #endif 2545 %} 2546 2547 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2548 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2549 MacroAssembler _masm(&cbuf); 2550 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2551 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2552 %} 2553 2554 // Load acquire. 2555 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2557 MacroAssembler _masm(&cbuf); 2558 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2559 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2560 __ twi_0($dst$$Register); 2561 __ isync(); 2562 %} 2563 2564 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2565 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2566 2567 MacroAssembler _masm(&cbuf); 2568 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2569 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2570 %} 2571 2572 // Load acquire. 2573 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2574 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2575 2576 MacroAssembler _masm(&cbuf); 2577 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2578 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2579 __ twi_0($dst$$Register); 2580 __ isync(); 2581 %} 2582 2583 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2584 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2585 2586 MacroAssembler _masm(&cbuf); 2587 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2588 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2589 %} 2590 2591 // Load acquire. 2592 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2594 2595 MacroAssembler _masm(&cbuf); 2596 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2597 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2598 __ twi_0($dst$$Register); 2599 __ isync(); 2600 %} 2601 2602 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2603 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2604 MacroAssembler _masm(&cbuf); 2605 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2606 // Operand 'ds' requires 4-alignment. 2607 assert((Idisp & 0x3) == 0, "unaligned offset"); 2608 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2609 %} 2610 2611 // Load acquire. 2612 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2613 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2614 MacroAssembler _masm(&cbuf); 2615 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2616 // Operand 'ds' requires 4-alignment. 2617 assert((Idisp & 0x3) == 0, "unaligned offset"); 2618 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2619 __ twi_0($dst$$Register); 2620 __ isync(); 2621 %} 2622 2623 enc_class enc_lfd(RegF dst, memory mem) %{ 2624 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2625 MacroAssembler _masm(&cbuf); 2626 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2627 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2628 %} 2629 2630 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2631 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2632 2633 MacroAssembler _masm(&cbuf); 2634 int toc_offset = 0; 2635 2636 address const_toc_addr; 2637 // Create a non-oop constant, no relocation needed. 2638 // If it is an IC, it has a virtual_call_Relocation. 2639 const_toc_addr = __ long_constant((jlong)$src$$constant); 2640 if (const_toc_addr == NULL) { 2641 ciEnv::current()->record_out_of_memory_failure(); 2642 return; 2643 } 2644 2645 // Get the constant's TOC offset. 2646 toc_offset = __ offset_to_method_toc(const_toc_addr); 2647 2648 // Keep the current instruction offset in mind. 2649 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2650 2651 __ ld($dst$$Register, toc_offset, $toc$$Register); 2652 %} 2653 2654 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2655 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2656 2657 MacroAssembler _masm(&cbuf); 2658 2659 if (!ra_->C->in_scratch_emit_size()) { 2660 address const_toc_addr; 2661 // Create a non-oop constant, no relocation needed. 2662 // If it is an IC, it has a virtual_call_Relocation. 2663 const_toc_addr = __ long_constant((jlong)$src$$constant); 2664 if (const_toc_addr == NULL) { 2665 ciEnv::current()->record_out_of_memory_failure(); 2666 return; 2667 } 2668 2669 // Get the constant's TOC offset. 2670 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2671 // Store the toc offset of the constant. 2672 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2673 2674 // Also keep the current instruction offset in mind. 2675 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2676 } 2677 2678 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2679 %} 2680 2681 %} // encode 2682 2683 source %{ 2684 2685 typedef struct { 2686 loadConL_hiNode *_large_hi; 2687 loadConL_loNode *_large_lo; 2688 loadConLNode *_small; 2689 MachNode *_last; 2690 } loadConLNodesTuple; 2691 2692 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2693 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2694 loadConLNodesTuple nodes; 2695 2696 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2697 if (large_constant_pool) { 2698 // Create new nodes. 2699 loadConL_hiNode *m1 = new loadConL_hiNode(); 2700 loadConL_loNode *m2 = new loadConL_loNode(); 2701 2702 // inputs for new nodes 2703 m1->add_req(NULL, toc); 2704 m2->add_req(NULL, m1); 2705 2706 // operands for new nodes 2707 m1->_opnds[0] = new iRegLdstOper(); // dst 2708 m1->_opnds[1] = immSrc; // src 2709 m1->_opnds[2] = new iRegPdstOper(); // toc 2710 m2->_opnds[0] = new iRegLdstOper(); // dst 2711 m2->_opnds[1] = immSrc; // src 2712 m2->_opnds[2] = new iRegLdstOper(); // base 2713 2714 // Initialize ins_attrib TOC fields. 2715 m1->_const_toc_offset = -1; 2716 m2->_const_toc_offset_hi_node = m1; 2717 2718 // Initialize ins_attrib instruction offset. 2719 m1->_cbuf_insts_offset = -1; 2720 2721 // register allocation for new nodes 2722 ra_->set_pair(m1->_idx, reg_second, reg_first); 2723 ra_->set_pair(m2->_idx, reg_second, reg_first); 2724 2725 // Create result. 2726 nodes._large_hi = m1; 2727 nodes._large_lo = m2; 2728 nodes._small = NULL; 2729 nodes._last = nodes._large_lo; 2730 assert(m2->bottom_type()->isa_long(), "must be long"); 2731 } else { 2732 loadConLNode *m2 = new loadConLNode(); 2733 2734 // inputs for new nodes 2735 m2->add_req(NULL, toc); 2736 2737 // operands for new nodes 2738 m2->_opnds[0] = new iRegLdstOper(); // dst 2739 m2->_opnds[1] = immSrc; // src 2740 m2->_opnds[2] = new iRegPdstOper(); // toc 2741 2742 // Initialize ins_attrib instruction offset. 2743 m2->_cbuf_insts_offset = -1; 2744 2745 // register allocation for new nodes 2746 ra_->set_pair(m2->_idx, reg_second, reg_first); 2747 2748 // Create result. 2749 nodes._large_hi = NULL; 2750 nodes._large_lo = NULL; 2751 nodes._small = m2; 2752 nodes._last = nodes._small; 2753 assert(m2->bottom_type()->isa_long(), "must be long"); 2754 } 2755 2756 return nodes; 2757 } 2758 2759 typedef struct { 2760 loadConL_hiNode *_large_hi; 2761 loadConL_loNode *_large_lo; 2762 mtvsrdNode *_moved; 2763 xxspltdNode *_replicated; 2764 loadConLNode *_small; 2765 MachNode *_last; 2766 } loadConLReplicatedNodesTuple; 2767 2768 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2769 vecXOper *dst, immI_0Oper *zero, 2770 OptoReg::Name reg_second, OptoReg::Name reg_first, 2771 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2772 loadConLReplicatedNodesTuple nodes; 2773 2774 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2775 if (large_constant_pool) { 2776 // Create new nodes. 2777 loadConL_hiNode *m1 = new loadConL_hiNode(); 2778 loadConL_loNode *m2 = new loadConL_loNode(); 2779 mtvsrdNode *m3 = new mtvsrdNode(); 2780 xxspltdNode *m4 = new xxspltdNode(); 2781 2782 // inputs for new nodes 2783 m1->add_req(NULL, toc); 2784 m2->add_req(NULL, m1); 2785 m3->add_req(NULL, m2); 2786 m4->add_req(NULL, m3); 2787 2788 // operands for new nodes 2789 m1->_opnds[0] = new iRegLdstOper(); // dst 2790 m1->_opnds[1] = immSrc; // src 2791 m1->_opnds[2] = new iRegPdstOper(); // toc 2792 2793 m2->_opnds[0] = new iRegLdstOper(); // dst 2794 m2->_opnds[1] = immSrc; // src 2795 m2->_opnds[2] = new iRegLdstOper(); // base 2796 2797 m3->_opnds[0] = new vecXOper(); // dst 2798 m3->_opnds[1] = new iRegLdstOper(); // src 2799 2800 m4->_opnds[0] = new vecXOper(); // dst 2801 m4->_opnds[1] = new vecXOper(); // src 2802 m4->_opnds[2] = zero; 2803 2804 // Initialize ins_attrib TOC fields. 2805 m1->_const_toc_offset = -1; 2806 m2->_const_toc_offset_hi_node = m1; 2807 2808 // Initialize ins_attrib instruction offset. 2809 m1->_cbuf_insts_offset = -1; 2810 2811 // register allocation for new nodes 2812 ra_->set_pair(m1->_idx, reg_second, reg_first); 2813 ra_->set_pair(m2->_idx, reg_second, reg_first); 2814 ra_->set1(m3->_idx, reg_second); 2815 ra_->set2(m3->_idx, reg_vec_first); 2816 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2817 2818 // Create result. 2819 nodes._large_hi = m1; 2820 nodes._large_lo = m2; 2821 nodes._moved = m3; 2822 nodes._replicated = m4; 2823 nodes._small = NULL; 2824 nodes._last = nodes._replicated; 2825 assert(m2->bottom_type()->isa_long(), "must be long"); 2826 } else { 2827 loadConLNode *m2 = new loadConLNode(); 2828 mtvsrdNode *m3 = new mtvsrdNode(); 2829 xxspltdNode *m4 = new xxspltdNode(); 2830 2831 // inputs for new nodes 2832 m2->add_req(NULL, toc); 2833 2834 // operands for new nodes 2835 m2->_opnds[0] = new iRegLdstOper(); // dst 2836 m2->_opnds[1] = immSrc; // src 2837 m2->_opnds[2] = new iRegPdstOper(); // toc 2838 2839 m3->_opnds[0] = new vecXOper(); // dst 2840 m3->_opnds[1] = new iRegLdstOper(); // src 2841 2842 m4->_opnds[0] = new vecXOper(); // dst 2843 m4->_opnds[1] = new vecXOper(); // src 2844 m4->_opnds[2] = zero; 2845 2846 // Initialize ins_attrib instruction offset. 2847 m2->_cbuf_insts_offset = -1; 2848 ra_->set1(m3->_idx, reg_second); 2849 ra_->set2(m3->_idx, reg_vec_first); 2850 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2851 2852 // register allocation for new nodes 2853 ra_->set_pair(m2->_idx, reg_second, reg_first); 2854 2855 // Create result. 2856 nodes._large_hi = NULL; 2857 nodes._large_lo = NULL; 2858 nodes._small = m2; 2859 nodes._moved = m3; 2860 nodes._replicated = m4; 2861 nodes._last = nodes._replicated; 2862 assert(m2->bottom_type()->isa_long(), "must be long"); 2863 } 2864 2865 return nodes; 2866 } 2867 2868 %} // source 2869 2870 encode %{ 2871 // Postalloc expand emitter for loading a long constant from the method's TOC. 2872 // Enc_class needed as consttanttablebase is not supported by postalloc 2873 // expand. 2874 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2875 // Create new nodes. 2876 loadConLNodesTuple loadConLNodes = 2877 loadConLNodesTuple_create(ra_, n_toc, op_src, 2878 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2879 2880 // Push new nodes. 2881 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2882 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2883 2884 // some asserts 2885 assert(nodes->length() >= 1, "must have created at least 1 node"); 2886 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2887 %} 2888 2889 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2890 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2891 2892 MacroAssembler _masm(&cbuf); 2893 int toc_offset = 0; 2894 2895 intptr_t val = $src$$constant; 2896 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2897 address const_toc_addr; 2898 if (constant_reloc == relocInfo::oop_type) { 2899 // Create an oop constant and a corresponding relocation. 2900 AddressLiteral a = __ allocate_oop_address((jobject)val); 2901 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2902 __ relocate(a.rspec()); 2903 } else if (constant_reloc == relocInfo::metadata_type) { 2904 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2905 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2906 __ relocate(a.rspec()); 2907 } else { 2908 // Create a non-oop constant, no relocation needed. 2909 const_toc_addr = __ long_constant((jlong)$src$$constant); 2910 } 2911 2912 if (const_toc_addr == NULL) { 2913 ciEnv::current()->record_out_of_memory_failure(); 2914 return; 2915 } 2916 // Get the constant's TOC offset. 2917 toc_offset = __ offset_to_method_toc(const_toc_addr); 2918 2919 __ ld($dst$$Register, toc_offset, $toc$$Register); 2920 %} 2921 2922 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2923 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2924 2925 MacroAssembler _masm(&cbuf); 2926 if (!ra_->C->in_scratch_emit_size()) { 2927 intptr_t val = $src$$constant; 2928 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2929 address const_toc_addr; 2930 if (constant_reloc == relocInfo::oop_type) { 2931 // Create an oop constant and a corresponding relocation. 2932 AddressLiteral a = __ allocate_oop_address((jobject)val); 2933 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2934 __ relocate(a.rspec()); 2935 } else if (constant_reloc == relocInfo::metadata_type) { 2936 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2937 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2938 __ relocate(a.rspec()); 2939 } else { // non-oop pointers, e.g. card mark base, heap top 2940 // Create a non-oop constant, no relocation needed. 2941 const_toc_addr = __ long_constant((jlong)$src$$constant); 2942 } 2943 2944 if (const_toc_addr == NULL) { 2945 ciEnv::current()->record_out_of_memory_failure(); 2946 return; 2947 } 2948 // Get the constant's TOC offset. 2949 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2950 // Store the toc offset of the constant. 2951 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2952 } 2953 2954 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2955 %} 2956 2957 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2958 // Enc_class needed as consttanttablebase is not supported by postalloc 2959 // expand. 2960 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2961 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2962 if (large_constant_pool) { 2963 // Create new nodes. 2964 loadConP_hiNode *m1 = new loadConP_hiNode(); 2965 loadConP_loNode *m2 = new loadConP_loNode(); 2966 2967 // inputs for new nodes 2968 m1->add_req(NULL, n_toc); 2969 m2->add_req(NULL, m1); 2970 2971 // operands for new nodes 2972 m1->_opnds[0] = new iRegPdstOper(); // dst 2973 m1->_opnds[1] = op_src; // src 2974 m1->_opnds[2] = new iRegPdstOper(); // toc 2975 m2->_opnds[0] = new iRegPdstOper(); // dst 2976 m2->_opnds[1] = op_src; // src 2977 m2->_opnds[2] = new iRegLdstOper(); // base 2978 2979 // Initialize ins_attrib TOC fields. 2980 m1->_const_toc_offset = -1; 2981 m2->_const_toc_offset_hi_node = m1; 2982 2983 // Register allocation for new nodes. 2984 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2985 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2986 2987 nodes->push(m1); 2988 nodes->push(m2); 2989 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2990 } else { 2991 loadConPNode *m2 = new loadConPNode(); 2992 2993 // inputs for new nodes 2994 m2->add_req(NULL, n_toc); 2995 2996 // operands for new nodes 2997 m2->_opnds[0] = new iRegPdstOper(); // dst 2998 m2->_opnds[1] = op_src; // src 2999 m2->_opnds[2] = new iRegPdstOper(); // toc 3000 3001 // Register allocation for new nodes. 3002 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3003 3004 nodes->push(m2); 3005 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3006 } 3007 %} 3008 3009 // Enc_class needed as consttanttablebase is not supported by postalloc 3010 // expand. 3011 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3012 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3013 3014 MachNode *m2; 3015 if (large_constant_pool) { 3016 m2 = new loadConFCompNode(); 3017 } else { 3018 m2 = new loadConFNode(); 3019 } 3020 // inputs for new nodes 3021 m2->add_req(NULL, n_toc); 3022 3023 // operands for new nodes 3024 m2->_opnds[0] = op_dst; 3025 m2->_opnds[1] = op_src; 3026 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3027 3028 // register allocation for new nodes 3029 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3030 nodes->push(m2); 3031 %} 3032 3033 // Enc_class needed as consttanttablebase is not supported by postalloc 3034 // expand. 3035 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3036 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3037 3038 MachNode *m2; 3039 if (large_constant_pool) { 3040 m2 = new loadConDCompNode(); 3041 } else { 3042 m2 = new loadConDNode(); 3043 } 3044 // inputs for new nodes 3045 m2->add_req(NULL, n_toc); 3046 3047 // operands for new nodes 3048 m2->_opnds[0] = op_dst; 3049 m2->_opnds[1] = op_src; 3050 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3051 3052 // register allocation for new nodes 3053 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3054 nodes->push(m2); 3055 %} 3056 3057 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3058 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3059 MacroAssembler _masm(&cbuf); 3060 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3061 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3062 %} 3063 3064 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3065 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3066 MacroAssembler _masm(&cbuf); 3067 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3068 // Operand 'ds' requires 4-alignment. 3069 assert((Idisp & 0x3) == 0, "unaligned offset"); 3070 __ std($src$$Register, Idisp, $mem$$base$$Register); 3071 %} 3072 3073 enc_class enc_stfs(RegF src, memory mem) %{ 3074 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3075 MacroAssembler _masm(&cbuf); 3076 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3077 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3078 %} 3079 3080 enc_class enc_stfd(RegF src, memory mem) %{ 3081 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3082 MacroAssembler _masm(&cbuf); 3083 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3084 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3085 %} 3086 3087 // Use release_store for card-marking to ensure that previous 3088 // oop-stores are visible before the card-mark change. 3089 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3090 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3091 // FIXME: Implement this as a cmove and use a fixed condition code 3092 // register which is written on every transition to compiled code, 3093 // e.g. in call-stub and when returning from runtime stubs. 3094 // 3095 // Proposed code sequence for the cmove implementation: 3096 // 3097 // Label skip_release; 3098 // __ beq(CCRfixed, skip_release); 3099 // __ release(); 3100 // __ bind(skip_release); 3101 // __ stb(card mark); 3102 3103 MacroAssembler _masm(&cbuf); 3104 Label skip_storestore; 3105 3106 #if 0 // TODO: PPC port 3107 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 3108 // StoreStore barrier conditionally. 3109 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3110 __ cmpwi($crx$$CondRegister, R0, 0); 3111 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3112 #endif 3113 __ li(R0, 0); 3114 __ membar(Assembler::StoreStore); 3115 #if 0 // TODO: PPC port 3116 __ bind(skip_storestore); 3117 #endif 3118 3119 // Do the store. 3120 if ($mem$$index == 0) { 3121 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3122 } else { 3123 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3124 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3125 } 3126 %} 3127 3128 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3129 3130 if (VM_Version::has_isel()) { 3131 // use isel instruction with Power 7 3132 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3133 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3134 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3135 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3136 3137 n_compare->add_req(n_region, n_src); 3138 n_compare->_opnds[0] = op_crx; 3139 n_compare->_opnds[1] = op_src; 3140 n_compare->_opnds[2] = new immL16Oper(0); 3141 3142 n_sub_base->add_req(n_region, n_src); 3143 n_sub_base->_opnds[0] = op_dst; 3144 n_sub_base->_opnds[1] = op_src; 3145 n_sub_base->_bottom_type = _bottom_type; 3146 3147 n_shift->add_req(n_region, n_sub_base); 3148 n_shift->_opnds[0] = op_dst; 3149 n_shift->_opnds[1] = op_dst; 3150 n_shift->_bottom_type = _bottom_type; 3151 3152 n_cond_set->add_req(n_region, n_compare, n_shift); 3153 n_cond_set->_opnds[0] = op_dst; 3154 n_cond_set->_opnds[1] = op_crx; 3155 n_cond_set->_opnds[2] = op_dst; 3156 n_cond_set->_bottom_type = _bottom_type; 3157 3158 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3159 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3160 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3161 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3162 3163 nodes->push(n_compare); 3164 nodes->push(n_sub_base); 3165 nodes->push(n_shift); 3166 nodes->push(n_cond_set); 3167 3168 } else { 3169 // before Power 7 3170 moveRegNode *n_move = new moveRegNode(); 3171 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3172 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3173 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3174 3175 n_move->add_req(n_region, n_src); 3176 n_move->_opnds[0] = op_dst; 3177 n_move->_opnds[1] = op_src; 3178 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3179 3180 n_compare->add_req(n_region, n_src); 3181 n_compare->add_prec(n_move); 3182 3183 n_compare->_opnds[0] = op_crx; 3184 n_compare->_opnds[1] = op_src; 3185 n_compare->_opnds[2] = new immL16Oper(0); 3186 3187 n_sub_base->add_req(n_region, n_compare, n_src); 3188 n_sub_base->_opnds[0] = op_dst; 3189 n_sub_base->_opnds[1] = op_crx; 3190 n_sub_base->_opnds[2] = op_src; 3191 n_sub_base->_bottom_type = _bottom_type; 3192 3193 n_shift->add_req(n_region, n_sub_base); 3194 n_shift->_opnds[0] = op_dst; 3195 n_shift->_opnds[1] = op_dst; 3196 n_shift->_bottom_type = _bottom_type; 3197 3198 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3199 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3200 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3201 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3202 3203 nodes->push(n_move); 3204 nodes->push(n_compare); 3205 nodes->push(n_sub_base); 3206 nodes->push(n_shift); 3207 } 3208 3209 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3210 %} 3211 3212 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3213 3214 encodeP_subNode *n1 = new encodeP_subNode(); 3215 n1->add_req(n_region, n_src); 3216 n1->_opnds[0] = op_dst; 3217 n1->_opnds[1] = op_src; 3218 n1->_bottom_type = _bottom_type; 3219 3220 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3221 n2->add_req(n_region, n1); 3222 n2->_opnds[0] = op_dst; 3223 n2->_opnds[1] = op_dst; 3224 n2->_bottom_type = _bottom_type; 3225 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3226 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3227 3228 nodes->push(n1); 3229 nodes->push(n2); 3230 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3231 %} 3232 3233 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3234 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3235 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3236 3237 n_compare->add_req(n_region, n_src); 3238 n_compare->_opnds[0] = op_crx; 3239 n_compare->_opnds[1] = op_src; 3240 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3241 3242 n_shift->add_req(n_region, n_src); 3243 n_shift->_opnds[0] = op_dst; 3244 n_shift->_opnds[1] = op_src; 3245 n_shift->_bottom_type = _bottom_type; 3246 3247 if (VM_Version::has_isel()) { 3248 // use isel instruction with Power 7 3249 3250 decodeN_addNode *n_add_base = new decodeN_addNode(); 3251 n_add_base->add_req(n_region, n_shift); 3252 n_add_base->_opnds[0] = op_dst; 3253 n_add_base->_opnds[1] = op_dst; 3254 n_add_base->_bottom_type = _bottom_type; 3255 3256 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3257 n_cond_set->add_req(n_region, n_compare, n_add_base); 3258 n_cond_set->_opnds[0] = op_dst; 3259 n_cond_set->_opnds[1] = op_crx; 3260 n_cond_set->_opnds[2] = op_dst; 3261 n_cond_set->_bottom_type = _bottom_type; 3262 3263 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3264 ra_->set_oop(n_cond_set, true); 3265 3266 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3267 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3268 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3269 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3270 3271 nodes->push(n_compare); 3272 nodes->push(n_shift); 3273 nodes->push(n_add_base); 3274 nodes->push(n_cond_set); 3275 3276 } else { 3277 // before Power 7 3278 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3279 3280 n_add_base->add_req(n_region, n_compare, n_shift); 3281 n_add_base->_opnds[0] = op_dst; 3282 n_add_base->_opnds[1] = op_crx; 3283 n_add_base->_opnds[2] = op_dst; 3284 n_add_base->_bottom_type = _bottom_type; 3285 3286 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3287 ra_->set_oop(n_add_base, true); 3288 3289 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3290 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3291 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3292 3293 nodes->push(n_compare); 3294 nodes->push(n_shift); 3295 nodes->push(n_add_base); 3296 } 3297 %} 3298 3299 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3300 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3301 n1->add_req(n_region, n_src); 3302 n1->_opnds[0] = op_dst; 3303 n1->_opnds[1] = op_src; 3304 n1->_bottom_type = _bottom_type; 3305 3306 decodeN_addNode *n2 = new decodeN_addNode(); 3307 n2->add_req(n_region, n1); 3308 n2->_opnds[0] = op_dst; 3309 n2->_opnds[1] = op_dst; 3310 n2->_bottom_type = _bottom_type; 3311 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3312 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3313 3314 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3315 ra_->set_oop(n2, true); 3316 3317 nodes->push(n1); 3318 nodes->push(n2); 3319 %} 3320 3321 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3322 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3323 3324 MacroAssembler _masm(&cbuf); 3325 int cc = $cmp$$cmpcode; 3326 int flags_reg = $crx$$reg; 3327 Label done; 3328 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3329 // Branch if not (cmp crx). 3330 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3331 __ mr($dst$$Register, $src$$Register); 3332 // TODO PPC port __ endgroup_if_needed(_size == 12); 3333 __ bind(done); 3334 %} 3335 3336 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3337 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3338 3339 MacroAssembler _masm(&cbuf); 3340 Label done; 3341 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3342 // Branch if not (cmp crx). 3343 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3344 __ li($dst$$Register, $src$$constant); 3345 // TODO PPC port __ endgroup_if_needed(_size == 12); 3346 __ bind(done); 3347 %} 3348 3349 // This enc_class is needed so that scheduler gets proper 3350 // input mapping for latency computation. 3351 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3352 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3353 MacroAssembler _masm(&cbuf); 3354 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3355 %} 3356 3357 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3358 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3359 3360 MacroAssembler _masm(&cbuf); 3361 3362 Label done; 3363 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3364 __ li($dst$$Register, $zero$$constant); 3365 __ beq($crx$$CondRegister, done); 3366 __ li($dst$$Register, $notzero$$constant); 3367 __ bind(done); 3368 %} 3369 3370 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3371 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3372 3373 MacroAssembler _masm(&cbuf); 3374 3375 Label done; 3376 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3377 __ li($dst$$Register, $zero$$constant); 3378 __ beq($crx$$CondRegister, done); 3379 __ li($dst$$Register, $notzero$$constant); 3380 __ bind(done); 3381 %} 3382 3383 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3384 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3385 3386 MacroAssembler _masm(&cbuf); 3387 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3388 Label done; 3389 __ bso($crx$$CondRegister, done); 3390 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3391 // TODO PPC port __ endgroup_if_needed(_size == 12); 3392 __ bind(done); 3393 %} 3394 3395 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3396 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3397 3398 MacroAssembler _masm(&cbuf); 3399 Label done; 3400 __ bso($crx$$CondRegister, done); 3401 __ mffprd($dst$$Register, $src$$FloatRegister); 3402 // TODO PPC port __ endgroup_if_needed(_size == 12); 3403 __ bind(done); 3404 %} 3405 3406 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3407 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3408 3409 MacroAssembler _masm(&cbuf); 3410 Label d; // dummy 3411 __ bind(d); 3412 Label* p = ($lbl$$label); 3413 // `p' is `NULL' when this encoding class is used only to 3414 // determine the size of the encoded instruction. 3415 Label& l = (NULL == p)? d : *(p); 3416 int cc = $cmp$$cmpcode; 3417 int flags_reg = $crx$$reg; 3418 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3419 int bhint = Assembler::bhintNoHint; 3420 3421 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3422 if (_prob <= PROB_NEVER) { 3423 bhint = Assembler::bhintIsNotTaken; 3424 } else if (_prob >= PROB_ALWAYS) { 3425 bhint = Assembler::bhintIsTaken; 3426 } 3427 } 3428 3429 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3430 cc_to_biint(cc, flags_reg), 3431 l); 3432 %} 3433 3434 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3435 // The scheduler doesn't know about branch shortening, so we set the opcode 3436 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3437 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3438 3439 MacroAssembler _masm(&cbuf); 3440 Label d; // dummy 3441 __ bind(d); 3442 Label* p = ($lbl$$label); 3443 // `p' is `NULL' when this encoding class is used only to 3444 // determine the size of the encoded instruction. 3445 Label& l = (NULL == p)? d : *(p); 3446 int cc = $cmp$$cmpcode; 3447 int flags_reg = $crx$$reg; 3448 int bhint = Assembler::bhintNoHint; 3449 3450 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3451 if (_prob <= PROB_NEVER) { 3452 bhint = Assembler::bhintIsNotTaken; 3453 } else if (_prob >= PROB_ALWAYS) { 3454 bhint = Assembler::bhintIsTaken; 3455 } 3456 } 3457 3458 // Tell the conditional far branch to optimize itself when being relocated. 3459 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3460 cc_to_biint(cc, flags_reg), 3461 l, 3462 MacroAssembler::bc_far_optimize_on_relocate); 3463 %} 3464 3465 // Branch used with Power6 scheduling (can be shortened without changing the node). 3466 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3467 // The scheduler doesn't know about branch shortening, so we set the opcode 3468 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3469 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3470 3471 MacroAssembler _masm(&cbuf); 3472 Label d; // dummy 3473 __ bind(d); 3474 Label* p = ($lbl$$label); 3475 // `p' is `NULL' when this encoding class is used only to 3476 // determine the size of the encoded instruction. 3477 Label& l = (NULL == p)? d : *(p); 3478 int cc = $cmp$$cmpcode; 3479 int flags_reg = $crx$$reg; 3480 int bhint = Assembler::bhintNoHint; 3481 3482 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3483 if (_prob <= PROB_NEVER) { 3484 bhint = Assembler::bhintIsNotTaken; 3485 } else if (_prob >= PROB_ALWAYS) { 3486 bhint = Assembler::bhintIsTaken; 3487 } 3488 } 3489 3490 #if 0 // TODO: PPC port 3491 if (_size == 8) { 3492 // Tell the conditional far branch to optimize itself when being relocated. 3493 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3494 cc_to_biint(cc, flags_reg), 3495 l, 3496 MacroAssembler::bc_far_optimize_on_relocate); 3497 } else { 3498 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3499 cc_to_biint(cc, flags_reg), 3500 l); 3501 } 3502 #endif 3503 Unimplemented(); 3504 %} 3505 3506 // Postalloc expand emitter for loading a replicatef float constant from 3507 // the method's TOC. 3508 // Enc_class needed as consttanttablebase is not supported by postalloc 3509 // expand. 3510 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3511 // Create new nodes. 3512 3513 // Make an operand with the bit pattern to load as float. 3514 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3515 3516 loadConLNodesTuple loadConLNodes = 3517 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3518 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3519 3520 // Push new nodes. 3521 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3522 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3523 3524 assert(nodes->length() >= 1, "must have created at least 1 node"); 3525 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3526 %} 3527 3528 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc) %{ 3529 // Create new nodes. 3530 3531 // Make an operand with the bit pattern to load as float. 3532 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3533 immI_0Oper *op_zero = new immI_0Oper(0); 3534 3535 loadConLReplicatedNodesTuple loadConLNodes = 3536 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3537 OptoReg::Name(R20_H_num), OptoReg::Name(R20_num), 3538 OptoReg::Name(VSR11_num), OptoReg::Name(VSR10_num)); 3539 3540 // Push new nodes. 3541 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3542 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3543 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3544 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3545 3546 assert(nodes->length() >= 1, "must have created at least 1 node"); 3547 %} 3548 3549 // This enc_class is needed so that scheduler gets proper 3550 // input mapping for latency computation. 3551 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3552 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3553 // Fake operand dst needed for PPC scheduler. 3554 assert($dst$$constant == 0x0, "dst must be 0x0"); 3555 3556 MacroAssembler _masm(&cbuf); 3557 // Mark the code position where the load from the safepoint 3558 // polling page was emitted as relocInfo::poll_type. 3559 __ relocate(relocInfo::poll_type); 3560 __ load_from_polling_page($poll$$Register); 3561 %} 3562 3563 // A Java static call or a runtime call. 3564 // 3565 // Branch-and-link relative to a trampoline. 3566 // The trampoline loads the target address and does a long branch to there. 3567 // In case we call java, the trampoline branches to a interpreter_stub 3568 // which loads the inline cache and the real call target from the constant pool. 3569 // 3570 // This basically looks like this: 3571 // 3572 // >>>> consts -+ -+ 3573 // | |- offset1 3574 // [call target1] | <-+ 3575 // [IC cache] |- offset2 3576 // [call target2] <--+ 3577 // 3578 // <<<< consts 3579 // >>>> insts 3580 // 3581 // bl offset16 -+ -+ ??? // How many bits available? 3582 // | | 3583 // <<<< insts | | 3584 // >>>> stubs | | 3585 // | |- trampoline_stub_Reloc 3586 // trampoline stub: | <-+ 3587 // r2 = toc | 3588 // r2 = [r2 + offset1] | // Load call target1 from const section 3589 // mtctr r2 | 3590 // bctr |- static_stub_Reloc 3591 // comp_to_interp_stub: <---+ 3592 // r1 = toc 3593 // ICreg = [r1 + IC_offset] // Load IC from const section 3594 // r1 = [r1 + offset2] // Load call target2 from const section 3595 // mtctr r1 3596 // bctr 3597 // 3598 // <<<< stubs 3599 // 3600 // The call instruction in the code either 3601 // - Branches directly to a compiled method if the offset is encodable in instruction. 3602 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3603 // - Branches to the compiled_to_interp stub if the target is interpreted. 3604 // 3605 // Further there are three relocations from the loads to the constants in 3606 // the constant section. 3607 // 3608 // Usage of r1 and r2 in the stubs allows to distinguish them. 3609 enc_class enc_java_static_call(method meth) %{ 3610 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3611 3612 MacroAssembler _masm(&cbuf); 3613 address entry_point = (address)$meth$$method; 3614 3615 if (!_method) { 3616 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3617 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3618 } else { 3619 // Remember the offset not the address. 3620 const int start_offset = __ offset(); 3621 3622 // The trampoline stub. 3623 // No entry point given, use the current pc. 3624 // Make sure branch fits into 3625 if (entry_point == 0) entry_point = __ pc(); 3626 3627 // Put the entry point as a constant into the constant pool. 3628 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3629 if (entry_point_toc_addr == NULL) { 3630 ciEnv::current()->record_out_of_memory_failure(); 3631 return; 3632 } 3633 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3634 3635 // Emit the trampoline stub which will be related to the branch-and-link below. 3636 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3637 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3638 int method_index = resolved_method_index(cbuf); 3639 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3640 : static_call_Relocation::spec(method_index)); 3641 3642 // The real call. 3643 // Note: At this point we do not have the address of the trampoline 3644 // stub, and the entry point might be too far away for bl, so __ pc() 3645 // serves as dummy and the bl will be patched later. 3646 cbuf.set_insts_mark(); 3647 __ bl(__ pc()); // Emits a relocation. 3648 3649 // The stub for call to interpreter. 3650 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3651 if (stub == NULL) { 3652 ciEnv::current()->record_failure("CodeCache is full"); 3653 return; 3654 } 3655 } 3656 %} 3657 3658 // Second node of expanded dynamic call - the call. 3659 enc_class enc_java_dynamic_call_sched(method meth) %{ 3660 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3661 3662 MacroAssembler _masm(&cbuf); 3663 3664 if (!ra_->C->in_scratch_emit_size()) { 3665 // Create a call trampoline stub for the given method. 3666 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3667 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3668 if (entry_point_const == NULL) { 3669 ciEnv::current()->record_out_of_memory_failure(); 3670 return; 3671 } 3672 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3673 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3674 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3675 3676 // Build relocation at call site with ic position as data. 3677 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3678 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3679 "must have one, but can't have both"); 3680 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3681 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3682 "must contain instruction offset"); 3683 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3684 ? _load_ic_hi_node->_cbuf_insts_offset 3685 : _load_ic_node->_cbuf_insts_offset; 3686 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3687 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3688 "should be load from TOC"); 3689 int method_index = resolved_method_index(cbuf); 3690 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3691 } 3692 3693 // At this point I do not have the address of the trampoline stub, 3694 // and the entry point might be too far away for bl. Pc() serves 3695 // as dummy and bl will be patched later. 3696 __ bl((address) __ pc()); 3697 %} 3698 3699 // postalloc expand emitter for virtual calls. 3700 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3701 3702 // Create the nodes for loading the IC from the TOC. 3703 loadConLNodesTuple loadConLNodes_IC = 3704 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3705 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3706 3707 // Create the call node. 3708 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3709 call->_method_handle_invoke = _method_handle_invoke; 3710 call->_vtable_index = _vtable_index; 3711 call->_method = _method; 3712 call->_bci = _bci; 3713 call->_optimized_virtual = _optimized_virtual; 3714 call->_tf = _tf; 3715 call->_entry_point = _entry_point; 3716 call->_cnt = _cnt; 3717 call->_argsize = _argsize; 3718 call->_oop_map = _oop_map; 3719 call->_jvms = _jvms; 3720 call->_jvmadj = _jvmadj; 3721 call->_in_rms = _in_rms; 3722 call->_nesting = _nesting; 3723 call->_override_symbolic_info = _override_symbolic_info; 3724 3725 // New call needs all inputs of old call. 3726 // Req... 3727 for (uint i = 0; i < req(); ++i) { 3728 // The expanded node does not need toc any more. 3729 // Add the inline cache constant here instead. This expresses the 3730 // register of the inline cache must be live at the call. 3731 // Else we would have to adapt JVMState by -1. 3732 if (i == mach_constant_base_node_input()) { 3733 call->add_req(loadConLNodes_IC._last); 3734 } else { 3735 call->add_req(in(i)); 3736 } 3737 } 3738 // ...as well as prec 3739 for (uint i = req(); i < len(); ++i) { 3740 call->add_prec(in(i)); 3741 } 3742 3743 // Remember nodes loading the inline cache into r19. 3744 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3745 call->_load_ic_node = loadConLNodes_IC._small; 3746 3747 // Operands for new nodes. 3748 call->_opnds[0] = _opnds[0]; 3749 call->_opnds[1] = _opnds[1]; 3750 3751 // Only the inline cache is associated with a register. 3752 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3753 3754 // Push new nodes. 3755 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3756 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3757 nodes->push(call); 3758 %} 3759 3760 // Compound version of call dynamic 3761 // Toc is only passed so that it can be used in ins_encode statement. 3762 // In the code we have to use $constanttablebase. 3763 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3764 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3765 MacroAssembler _masm(&cbuf); 3766 int start_offset = __ offset(); 3767 3768 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3769 #if 0 3770 int vtable_index = this->_vtable_index; 3771 if (_vtable_index < 0) { 3772 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3773 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3774 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3775 3776 // Virtual call relocation will point to ic load. 3777 address virtual_call_meta_addr = __ pc(); 3778 // Load a clear inline cache. 3779 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3780 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3781 if (!success) { 3782 ciEnv::current()->record_out_of_memory_failure(); 3783 return; 3784 } 3785 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3786 // to determine who we intended to call. 3787 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3788 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3789 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3790 "Fix constant in ret_addr_offset()"); 3791 } else { 3792 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3793 // Go thru the vtable. Get receiver klass. Receiver already 3794 // checked for non-null. If we'll go thru a C2I adapter, the 3795 // interpreter expects method in R19_method. 3796 3797 __ load_klass(R11_scratch1, R3); 3798 3799 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3800 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3801 __ li(R19_method, v_off); 3802 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3803 // NOTE: for vtable dispatches, the vtable entry will never be 3804 // null. However it may very well end up in handle_wrong_method 3805 // if the method is abstract for the particular class. 3806 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3807 // Call target. Either compiled code or C2I adapter. 3808 __ mtctr(R11_scratch1); 3809 __ bctrl(); 3810 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3811 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3812 } 3813 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3814 "Fix constant in ret_addr_offset()"); 3815 } 3816 #endif 3817 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3818 %} 3819 3820 // a runtime call 3821 enc_class enc_java_to_runtime_call (method meth) %{ 3822 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3823 3824 MacroAssembler _masm(&cbuf); 3825 const address start_pc = __ pc(); 3826 3827 #if defined(ABI_ELFv2) 3828 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3829 __ call_c(entry, relocInfo::runtime_call_type); 3830 #else 3831 // The function we're going to call. 3832 FunctionDescriptor fdtemp; 3833 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3834 3835 Register Rtoc = R12_scratch2; 3836 // Calculate the method's TOC. 3837 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3838 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3839 // pool entries; call_c_using_toc will optimize the call. 3840 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3841 if (!success) { 3842 ciEnv::current()->record_out_of_memory_failure(); 3843 return; 3844 } 3845 #endif 3846 3847 // Check the ret_addr_offset. 3848 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3849 "Fix constant in ret_addr_offset()"); 3850 %} 3851 3852 // Move to ctr for leaf call. 3853 // This enc_class is needed so that scheduler gets proper 3854 // input mapping for latency computation. 3855 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3856 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3857 MacroAssembler _masm(&cbuf); 3858 __ mtctr($src$$Register); 3859 %} 3860 3861 // Postalloc expand emitter for runtime leaf calls. 3862 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3863 loadConLNodesTuple loadConLNodes_Entry; 3864 #if defined(ABI_ELFv2) 3865 jlong entry_address = (jlong) this->entry_point(); 3866 assert(entry_address, "need address here"); 3867 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3868 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3869 #else 3870 // Get the struct that describes the function we are about to call. 3871 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3872 assert(fd, "need fd here"); 3873 jlong entry_address = (jlong) fd->entry(); 3874 // new nodes 3875 loadConLNodesTuple loadConLNodes_Env; 3876 loadConLNodesTuple loadConLNodes_Toc; 3877 3878 // Create nodes and operands for loading the entry point. 3879 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3880 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3881 3882 3883 // Create nodes and operands for loading the env pointer. 3884 if (fd->env() != NULL) { 3885 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3886 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3887 } else { 3888 loadConLNodes_Env._large_hi = NULL; 3889 loadConLNodes_Env._large_lo = NULL; 3890 loadConLNodes_Env._small = NULL; 3891 loadConLNodes_Env._last = new loadConL16Node(); 3892 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3893 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3894 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3895 } 3896 3897 // Create nodes and operands for loading the Toc point. 3898 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3899 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3900 #endif // ABI_ELFv2 3901 // mtctr node 3902 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3903 3904 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3905 mtctr->add_req(0, loadConLNodes_Entry._last); 3906 3907 mtctr->_opnds[0] = new iRegLdstOper(); 3908 mtctr->_opnds[1] = new iRegLdstOper(); 3909 3910 // call node 3911 MachCallLeafNode *call = new CallLeafDirectNode(); 3912 3913 call->_opnds[0] = _opnds[0]; 3914 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3915 3916 // Make the new call node look like the old one. 3917 call->_name = _name; 3918 call->_tf = _tf; 3919 call->_entry_point = _entry_point; 3920 call->_cnt = _cnt; 3921 call->_argsize = _argsize; 3922 call->_oop_map = _oop_map; 3923 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3924 call->_jvms = NULL; 3925 call->_jvmadj = _jvmadj; 3926 call->_in_rms = _in_rms; 3927 call->_nesting = _nesting; 3928 3929 3930 // New call needs all inputs of old call. 3931 // Req... 3932 for (uint i = 0; i < req(); ++i) { 3933 if (i != mach_constant_base_node_input()) { 3934 call->add_req(in(i)); 3935 } 3936 } 3937 3938 // These must be reqired edges, as the registers are live up to 3939 // the call. Else the constants are handled as kills. 3940 call->add_req(mtctr); 3941 #if !defined(ABI_ELFv2) 3942 call->add_req(loadConLNodes_Env._last); 3943 call->add_req(loadConLNodes_Toc._last); 3944 #endif 3945 3946 // ...as well as prec 3947 for (uint i = req(); i < len(); ++i) { 3948 call->add_prec(in(i)); 3949 } 3950 3951 // registers 3952 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3953 3954 // Insert the new nodes. 3955 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3956 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3957 #if !defined(ABI_ELFv2) 3958 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3959 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3960 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3961 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3962 #endif 3963 nodes->push(mtctr); 3964 nodes->push(call); 3965 %} 3966 %} 3967 3968 //----------FRAME-------------------------------------------------------------- 3969 // Definition of frame structure and management information. 3970 3971 frame %{ 3972 // What direction does stack grow in (assumed to be same for native & Java). 3973 stack_direction(TOWARDS_LOW); 3974 3975 // These two registers define part of the calling convention between 3976 // compiled code and the interpreter. 3977 3978 // Inline Cache Register or method for I2C. 3979 inline_cache_reg(R19); // R19_method 3980 3981 // Method Oop Register when calling interpreter. 3982 interpreter_method_oop_reg(R19); // R19_method 3983 3984 // Optional: name the operand used by cisc-spilling to access 3985 // [stack_pointer + offset]. 3986 cisc_spilling_operand_name(indOffset); 3987 3988 // Number of stack slots consumed by a Monitor enter. 3989 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3990 3991 // Compiled code's Frame Pointer. 3992 frame_pointer(R1); // R1_SP 3993 3994 // Interpreter stores its frame pointer in a register which is 3995 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3996 // interpreted java to compiled java. 3997 // 3998 // R14_state holds pointer to caller's cInterpreter. 3999 interpreter_frame_pointer(R14); // R14_state 4000 4001 stack_alignment(frame::alignment_in_bytes); 4002 4003 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4004 4005 // Number of outgoing stack slots killed above the 4006 // out_preserve_stack_slots for calls to C. Supports the var-args 4007 // backing area for register parms. 4008 // 4009 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4010 4011 // The after-PROLOG location of the return address. Location of 4012 // return address specifies a type (REG or STACK) and a number 4013 // representing the register number (i.e. - use a register name) or 4014 // stack slot. 4015 // 4016 // A: Link register is stored in stack slot ... 4017 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4018 // J: Therefore, we make sure that the link register is also in R11_scratch1 4019 // at the end of the prolog. 4020 // B: We use R20, now. 4021 //return_addr(REG R20); 4022 4023 // G: After reading the comments made by all the luminaries on their 4024 // failure to tell the compiler where the return address really is, 4025 // I hardly dare to try myself. However, I'm convinced it's in slot 4026 // 4 what apparently works and saves us some spills. 4027 return_addr(STACK 4); 4028 4029 // This is the body of the function 4030 // 4031 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4032 // uint length, // length of array 4033 // bool is_outgoing) 4034 // 4035 // The `sig' array is to be updated. sig[j] represents the location 4036 // of the j-th argument, either a register or a stack slot. 4037 4038 // Comment taken from i486.ad: 4039 // Body of function which returns an integer array locating 4040 // arguments either in registers or in stack slots. Passed an array 4041 // of ideal registers called "sig" and a "length" count. Stack-slot 4042 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4043 // arguments for a CALLEE. Incoming stack arguments are 4044 // automatically biased by the preserve_stack_slots field above. 4045 calling_convention %{ 4046 // No difference between ingoing/outgoing. Just pass false. 4047 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4048 %} 4049 4050 // Comment taken from i486.ad: 4051 // Body of function which returns an integer array locating 4052 // arguments either in registers or in stack slots. Passed an array 4053 // of ideal registers called "sig" and a "length" count. Stack-slot 4054 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4055 // arguments for a CALLEE. Incoming stack arguments are 4056 // automatically biased by the preserve_stack_slots field above. 4057 c_calling_convention %{ 4058 // This is obviously always outgoing. 4059 // C argument in register AND stack slot. 4060 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4061 %} 4062 4063 // Location of native (C/C++) and interpreter return values. This 4064 // is specified to be the same as Java. In the 32-bit VM, long 4065 // values are actually returned from native calls in O0:O1 and 4066 // returned to the interpreter in I0:I1. The copying to and from 4067 // the register pairs is done by the appropriate call and epilog 4068 // opcodes. This simplifies the register allocator. 4069 c_return_value %{ 4070 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4071 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4072 "only return normal values"); 4073 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4074 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4075 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4076 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4077 %} 4078 4079 // Location of compiled Java return values. Same as C 4080 return_value %{ 4081 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4082 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4083 "only return normal values"); 4084 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4085 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4086 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4087 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4088 %} 4089 %} 4090 4091 4092 //----------ATTRIBUTES--------------------------------------------------------- 4093 4094 //----------Operand Attributes------------------------------------------------- 4095 op_attrib op_cost(1); // Required cost attribute. 4096 4097 //----------Instruction Attributes--------------------------------------------- 4098 4099 // Cost attribute. required. 4100 ins_attrib ins_cost(DEFAULT_COST); 4101 4102 // Is this instruction a non-matching short branch variant of some 4103 // long branch? Not required. 4104 ins_attrib ins_short_branch(0); 4105 4106 ins_attrib ins_is_TrapBasedCheckNode(true); 4107 4108 // Number of constants. 4109 // This instruction uses the given number of constants 4110 // (optional attribute). 4111 // This is needed to determine in time whether the constant pool will 4112 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4113 // is determined. It's also used to compute the constant pool size 4114 // in Output(). 4115 ins_attrib ins_num_consts(0); 4116 4117 // Required alignment attribute (must be a power of 2) specifies the 4118 // alignment that some part of the instruction (not necessarily the 4119 // start) requires. If > 1, a compute_padding() function must be 4120 // provided for the instruction. 4121 ins_attrib ins_alignment(1); 4122 4123 // Enforce/prohibit rematerializations. 4124 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4125 // then rematerialization of that instruction is prohibited and the 4126 // instruction's value will be spilled if necessary. 4127 // Causes that MachNode::rematerialize() returns false. 4128 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4129 // then rematerialization should be enforced and a copy of the instruction 4130 // should be inserted if possible; rematerialization is not guaranteed. 4131 // Note: this may result in rematerializations in front of every use. 4132 // Causes that MachNode::rematerialize() can return true. 4133 // (optional attribute) 4134 ins_attrib ins_cannot_rematerialize(false); 4135 ins_attrib ins_should_rematerialize(false); 4136 4137 // Instruction has variable size depending on alignment. 4138 ins_attrib ins_variable_size_depending_on_alignment(false); 4139 4140 // Instruction is a nop. 4141 ins_attrib ins_is_nop(false); 4142 4143 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4144 ins_attrib ins_use_mach_if_fast_lock_node(false); 4145 4146 // Field for the toc offset of a constant. 4147 // 4148 // This is needed if the toc offset is not encodable as an immediate in 4149 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4150 // added to the toc, and from this a load with immediate is performed. 4151 // With postalloc expand, we get two nodes that require the same offset 4152 // but which don't know about each other. The offset is only known 4153 // when the constant is added to the constant pool during emitting. 4154 // It is generated in the 'hi'-node adding the upper bits, and saved 4155 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4156 // the offset from there when it gets encoded. 4157 ins_attrib ins_field_const_toc_offset(0); 4158 ins_attrib ins_field_const_toc_offset_hi_node(0); 4159 4160 // A field that can hold the instructions offset in the code buffer. 4161 // Set in the nodes emitter. 4162 ins_attrib ins_field_cbuf_insts_offset(-1); 4163 4164 // Fields for referencing a call's load-IC-node. 4165 // If the toc offset can not be encoded as an immediate in a load, we 4166 // use two nodes. 4167 ins_attrib ins_field_load_ic_hi_node(0); 4168 ins_attrib ins_field_load_ic_node(0); 4169 4170 //----------OPERANDS----------------------------------------------------------- 4171 // Operand definitions must precede instruction definitions for correct 4172 // parsing in the ADLC because operands constitute user defined types 4173 // which are used in instruction definitions. 4174 // 4175 // Formats are generated automatically for constants and base registers. 4176 4177 operand vecX() %{ 4178 constraint(ALLOC_IN_RC(vs_reg)); 4179 match(VecX); 4180 4181 format %{ %} 4182 interface(REG_INTER); 4183 %} 4184 4185 //----------Simple Operands---------------------------------------------------- 4186 // Immediate Operands 4187 4188 // Integer Immediate: 32-bit 4189 operand immI() %{ 4190 match(ConI); 4191 op_cost(40); 4192 format %{ %} 4193 interface(CONST_INTER); 4194 %} 4195 4196 operand immI8() %{ 4197 predicate(Assembler::is_simm(n->get_int(), 8)); 4198 op_cost(0); 4199 match(ConI); 4200 format %{ %} 4201 interface(CONST_INTER); 4202 %} 4203 4204 // Integer Immediate: 16-bit 4205 operand immI16() %{ 4206 predicate(Assembler::is_simm(n->get_int(), 16)); 4207 op_cost(0); 4208 match(ConI); 4209 format %{ %} 4210 interface(CONST_INTER); 4211 %} 4212 4213 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4214 operand immIhi16() %{ 4215 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4216 match(ConI); 4217 op_cost(0); 4218 format %{ %} 4219 interface(CONST_INTER); 4220 %} 4221 4222 operand immInegpow2() %{ 4223 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4224 match(ConI); 4225 op_cost(0); 4226 format %{ %} 4227 interface(CONST_INTER); 4228 %} 4229 4230 operand immIpow2minus1() %{ 4231 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4232 match(ConI); 4233 op_cost(0); 4234 format %{ %} 4235 interface(CONST_INTER); 4236 %} 4237 4238 operand immIpowerOf2() %{ 4239 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4240 match(ConI); 4241 op_cost(0); 4242 format %{ %} 4243 interface(CONST_INTER); 4244 %} 4245 4246 // Unsigned Integer Immediate: the values 0-31 4247 operand uimmI5() %{ 4248 predicate(Assembler::is_uimm(n->get_int(), 5)); 4249 match(ConI); 4250 op_cost(0); 4251 format %{ %} 4252 interface(CONST_INTER); 4253 %} 4254 4255 // Unsigned Integer Immediate: 6-bit 4256 operand uimmI6() %{ 4257 predicate(Assembler::is_uimm(n->get_int(), 6)); 4258 match(ConI); 4259 op_cost(0); 4260 format %{ %} 4261 interface(CONST_INTER); 4262 %} 4263 4264 // Unsigned Integer Immediate: 6-bit int, greater than 32 4265 operand uimmI6_ge32() %{ 4266 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4267 match(ConI); 4268 op_cost(0); 4269 format %{ %} 4270 interface(CONST_INTER); 4271 %} 4272 4273 // Unsigned Integer Immediate: 15-bit 4274 operand uimmI15() %{ 4275 predicate(Assembler::is_uimm(n->get_int(), 15)); 4276 match(ConI); 4277 op_cost(0); 4278 format %{ %} 4279 interface(CONST_INTER); 4280 %} 4281 4282 // Unsigned Integer Immediate: 16-bit 4283 operand uimmI16() %{ 4284 predicate(Assembler::is_uimm(n->get_int(), 16)); 4285 match(ConI); 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289 %} 4290 4291 // constant 'int 0'. 4292 operand immI_0() %{ 4293 predicate(n->get_int() == 0); 4294 match(ConI); 4295 op_cost(0); 4296 format %{ %} 4297 interface(CONST_INTER); 4298 %} 4299 4300 // constant 'int 1'. 4301 operand immI_1() %{ 4302 predicate(n->get_int() == 1); 4303 match(ConI); 4304 op_cost(0); 4305 format %{ %} 4306 interface(CONST_INTER); 4307 %} 4308 4309 // constant 'int -1'. 4310 operand immI_minus1() %{ 4311 predicate(n->get_int() == -1); 4312 match(ConI); 4313 op_cost(0); 4314 format %{ %} 4315 interface(CONST_INTER); 4316 %} 4317 4318 // int value 16. 4319 operand immI_16() %{ 4320 predicate(n->get_int() == 16); 4321 match(ConI); 4322 op_cost(0); 4323 format %{ %} 4324 interface(CONST_INTER); 4325 %} 4326 4327 // int value 24. 4328 operand immI_24() %{ 4329 predicate(n->get_int() == 24); 4330 match(ConI); 4331 op_cost(0); 4332 format %{ %} 4333 interface(CONST_INTER); 4334 %} 4335 4336 // Compressed oops constants 4337 // Pointer Immediate 4338 operand immN() %{ 4339 match(ConN); 4340 4341 op_cost(10); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // NULL Pointer Immediate 4347 operand immN_0() %{ 4348 predicate(n->get_narrowcon() == 0); 4349 match(ConN); 4350 4351 op_cost(0); 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Compressed klass constants 4357 operand immNKlass() %{ 4358 match(ConNKlass); 4359 4360 op_cost(0); 4361 format %{ %} 4362 interface(CONST_INTER); 4363 %} 4364 4365 // This operand can be used to avoid matching of an instruct 4366 // with chain rule. 4367 operand immNKlass_NM() %{ 4368 match(ConNKlass); 4369 predicate(false); 4370 op_cost(0); 4371 format %{ %} 4372 interface(CONST_INTER); 4373 %} 4374 4375 // Pointer Immediate: 64-bit 4376 operand immP() %{ 4377 match(ConP); 4378 op_cost(0); 4379 format %{ %} 4380 interface(CONST_INTER); 4381 %} 4382 4383 // Operand to avoid match of loadConP. 4384 // This operand can be used to avoid matching of an instruct 4385 // with chain rule. 4386 operand immP_NM() %{ 4387 match(ConP); 4388 predicate(false); 4389 op_cost(0); 4390 format %{ %} 4391 interface(CONST_INTER); 4392 %} 4393 4394 // costant 'pointer 0'. 4395 operand immP_0() %{ 4396 predicate(n->get_ptr() == 0); 4397 match(ConP); 4398 op_cost(0); 4399 format %{ %} 4400 interface(CONST_INTER); 4401 %} 4402 4403 // pointer 0x0 or 0x1 4404 operand immP_0or1() %{ 4405 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4406 match(ConP); 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410 %} 4411 4412 operand immL() %{ 4413 match(ConL); 4414 op_cost(40); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 operand immLmax30() %{ 4420 predicate((n->get_long() <= 30)); 4421 match(ConL); 4422 op_cost(0); 4423 format %{ %} 4424 interface(CONST_INTER); 4425 %} 4426 4427 // Long Immediate: 16-bit 4428 operand immL16() %{ 4429 predicate(Assembler::is_simm(n->get_long(), 16)); 4430 match(ConL); 4431 op_cost(0); 4432 format %{ %} 4433 interface(CONST_INTER); 4434 %} 4435 4436 // Long Immediate: 16-bit, 4-aligned 4437 operand immL16Alg4() %{ 4438 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4439 match(ConL); 4440 op_cost(0); 4441 format %{ %} 4442 interface(CONST_INTER); 4443 %} 4444 4445 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4446 operand immL32hi16() %{ 4447 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4448 match(ConL); 4449 op_cost(0); 4450 format %{ %} 4451 interface(CONST_INTER); 4452 %} 4453 4454 // Long Immediate: 32-bit 4455 operand immL32() %{ 4456 predicate(Assembler::is_simm(n->get_long(), 32)); 4457 match(ConL); 4458 op_cost(0); 4459 format %{ %} 4460 interface(CONST_INTER); 4461 %} 4462 4463 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4464 operand immLhighest16() %{ 4465 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4466 match(ConL); 4467 op_cost(0); 4468 format %{ %} 4469 interface(CONST_INTER); 4470 %} 4471 4472 operand immLnegpow2() %{ 4473 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4474 match(ConL); 4475 op_cost(0); 4476 format %{ %} 4477 interface(CONST_INTER); 4478 %} 4479 4480 operand immLpow2minus1() %{ 4481 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4482 (n->get_long() != (jlong)0xffffffffffffffffL)); 4483 match(ConL); 4484 op_cost(0); 4485 format %{ %} 4486 interface(CONST_INTER); 4487 %} 4488 4489 // constant 'long 0'. 4490 operand immL_0() %{ 4491 predicate(n->get_long() == 0L); 4492 match(ConL); 4493 op_cost(0); 4494 format %{ %} 4495 interface(CONST_INTER); 4496 %} 4497 4498 // constat ' long -1'. 4499 operand immL_minus1() %{ 4500 predicate(n->get_long() == -1L); 4501 match(ConL); 4502 op_cost(0); 4503 format %{ %} 4504 interface(CONST_INTER); 4505 %} 4506 4507 // Long Immediate: low 32-bit mask 4508 operand immL_32bits() %{ 4509 predicate(n->get_long() == 0xFFFFFFFFL); 4510 match(ConL); 4511 op_cost(0); 4512 format %{ %} 4513 interface(CONST_INTER); 4514 %} 4515 4516 // Unsigned Long Immediate: 16-bit 4517 operand uimmL16() %{ 4518 predicate(Assembler::is_uimm(n->get_long(), 16)); 4519 match(ConL); 4520 op_cost(0); 4521 format %{ %} 4522 interface(CONST_INTER); 4523 %} 4524 4525 // Float Immediate 4526 operand immF() %{ 4527 match(ConF); 4528 op_cost(40); 4529 format %{ %} 4530 interface(CONST_INTER); 4531 %} 4532 4533 // Float Immediate: +0.0f. 4534 operand immF_0() %{ 4535 predicate(jint_cast(n->getf()) == 0); 4536 match(ConF); 4537 4538 op_cost(0); 4539 format %{ %} 4540 interface(CONST_INTER); 4541 %} 4542 4543 // Double Immediate 4544 operand immD() %{ 4545 match(ConD); 4546 op_cost(40); 4547 format %{ %} 4548 interface(CONST_INTER); 4549 %} 4550 4551 // Integer Register Operands 4552 // Integer Destination Register 4553 // See definition of reg_class bits32_reg_rw. 4554 operand iRegIdst() %{ 4555 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4556 match(RegI); 4557 match(rscratch1RegI); 4558 match(rscratch2RegI); 4559 match(rarg1RegI); 4560 match(rarg2RegI); 4561 match(rarg3RegI); 4562 match(rarg4RegI); 4563 format %{ %} 4564 interface(REG_INTER); 4565 %} 4566 4567 // Integer Source Register 4568 // See definition of reg_class bits32_reg_ro. 4569 operand iRegIsrc() %{ 4570 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4571 match(RegI); 4572 match(rscratch1RegI); 4573 match(rscratch2RegI); 4574 match(rarg1RegI); 4575 match(rarg2RegI); 4576 match(rarg3RegI); 4577 match(rarg4RegI); 4578 format %{ %} 4579 interface(REG_INTER); 4580 %} 4581 4582 operand rscratch1RegI() %{ 4583 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4584 match(iRegIdst); 4585 format %{ %} 4586 interface(REG_INTER); 4587 %} 4588 4589 operand rscratch2RegI() %{ 4590 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4591 match(iRegIdst); 4592 format %{ %} 4593 interface(REG_INTER); 4594 %} 4595 4596 operand rarg1RegI() %{ 4597 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4598 match(iRegIdst); 4599 format %{ %} 4600 interface(REG_INTER); 4601 %} 4602 4603 operand rarg2RegI() %{ 4604 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4605 match(iRegIdst); 4606 format %{ %} 4607 interface(REG_INTER); 4608 %} 4609 4610 operand rarg3RegI() %{ 4611 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4612 match(iRegIdst); 4613 format %{ %} 4614 interface(REG_INTER); 4615 %} 4616 4617 operand rarg4RegI() %{ 4618 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4619 match(iRegIdst); 4620 format %{ %} 4621 interface(REG_INTER); 4622 %} 4623 4624 operand rarg1RegL() %{ 4625 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4626 match(iRegLdst); 4627 format %{ %} 4628 interface(REG_INTER); 4629 %} 4630 4631 operand rarg2RegL() %{ 4632 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4633 match(iRegLdst); 4634 format %{ %} 4635 interface(REG_INTER); 4636 %} 4637 4638 operand rarg3RegL() %{ 4639 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4640 match(iRegLdst); 4641 format %{ %} 4642 interface(REG_INTER); 4643 %} 4644 4645 operand rarg4RegL() %{ 4646 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4647 match(iRegLdst); 4648 format %{ %} 4649 interface(REG_INTER); 4650 %} 4651 4652 // Pointer Destination Register 4653 // See definition of reg_class bits64_reg_rw. 4654 operand iRegPdst() %{ 4655 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4656 match(RegP); 4657 match(rscratch1RegP); 4658 match(rscratch2RegP); 4659 match(rarg1RegP); 4660 match(rarg2RegP); 4661 match(rarg3RegP); 4662 match(rarg4RegP); 4663 format %{ %} 4664 interface(REG_INTER); 4665 %} 4666 4667 // Pointer Destination Register 4668 // Operand not using r11 and r12 (killed in epilog). 4669 operand iRegPdstNoScratch() %{ 4670 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4671 match(RegP); 4672 match(rarg1RegP); 4673 match(rarg2RegP); 4674 match(rarg3RegP); 4675 match(rarg4RegP); 4676 format %{ %} 4677 interface(REG_INTER); 4678 %} 4679 4680 // Pointer Source Register 4681 // See definition of reg_class bits64_reg_ro. 4682 operand iRegPsrc() %{ 4683 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4684 match(RegP); 4685 match(iRegPdst); 4686 match(rscratch1RegP); 4687 match(rscratch2RegP); 4688 match(rarg1RegP); 4689 match(rarg2RegP); 4690 match(rarg3RegP); 4691 match(rarg4RegP); 4692 match(threadRegP); 4693 format %{ %} 4694 interface(REG_INTER); 4695 %} 4696 4697 // Thread operand. 4698 operand threadRegP() %{ 4699 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4700 match(iRegPdst); 4701 format %{ "R16" %} 4702 interface(REG_INTER); 4703 %} 4704 4705 operand rscratch1RegP() %{ 4706 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4707 match(iRegPdst); 4708 format %{ "R11" %} 4709 interface(REG_INTER); 4710 %} 4711 4712 operand rscratch2RegP() %{ 4713 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4714 match(iRegPdst); 4715 format %{ %} 4716 interface(REG_INTER); 4717 %} 4718 4719 operand rarg1RegP() %{ 4720 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4721 match(iRegPdst); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 operand rarg2RegP() %{ 4727 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4728 match(iRegPdst); 4729 format %{ %} 4730 interface(REG_INTER); 4731 %} 4732 4733 operand rarg3RegP() %{ 4734 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4735 match(iRegPdst); 4736 format %{ %} 4737 interface(REG_INTER); 4738 %} 4739 4740 operand rarg4RegP() %{ 4741 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4742 match(iRegPdst); 4743 format %{ %} 4744 interface(REG_INTER); 4745 %} 4746 4747 operand iRegNsrc() %{ 4748 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4749 match(RegN); 4750 match(iRegNdst); 4751 4752 format %{ %} 4753 interface(REG_INTER); 4754 %} 4755 4756 operand iRegNdst() %{ 4757 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4758 match(RegN); 4759 4760 format %{ %} 4761 interface(REG_INTER); 4762 %} 4763 4764 // Long Destination Register 4765 // See definition of reg_class bits64_reg_rw. 4766 operand iRegLdst() %{ 4767 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4768 match(RegL); 4769 match(rscratch1RegL); 4770 match(rscratch2RegL); 4771 format %{ %} 4772 interface(REG_INTER); 4773 %} 4774 4775 // Long Source Register 4776 // See definition of reg_class bits64_reg_ro. 4777 operand iRegLsrc() %{ 4778 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4779 match(RegL); 4780 match(iRegLdst); 4781 match(rscratch1RegL); 4782 match(rscratch2RegL); 4783 format %{ %} 4784 interface(REG_INTER); 4785 %} 4786 4787 // Special operand for ConvL2I. 4788 operand iRegL2Isrc(iRegLsrc reg) %{ 4789 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4790 match(ConvL2I reg); 4791 format %{ "ConvL2I($reg)" %} 4792 interface(REG_INTER) 4793 %} 4794 4795 operand rscratch1RegL() %{ 4796 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4797 match(RegL); 4798 format %{ %} 4799 interface(REG_INTER); 4800 %} 4801 4802 operand rscratch2RegL() %{ 4803 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4804 match(RegL); 4805 format %{ %} 4806 interface(REG_INTER); 4807 %} 4808 4809 // Condition Code Flag Registers 4810 operand flagsReg() %{ 4811 constraint(ALLOC_IN_RC(int_flags)); 4812 match(RegFlags); 4813 format %{ %} 4814 interface(REG_INTER); 4815 %} 4816 4817 operand flagsRegSrc() %{ 4818 constraint(ALLOC_IN_RC(int_flags_ro)); 4819 match(RegFlags); 4820 match(flagsReg); 4821 match(flagsRegCR0); 4822 format %{ %} 4823 interface(REG_INTER); 4824 %} 4825 4826 // Condition Code Flag Register CR0 4827 operand flagsRegCR0() %{ 4828 constraint(ALLOC_IN_RC(int_flags_CR0)); 4829 match(RegFlags); 4830 format %{ "CR0" %} 4831 interface(REG_INTER); 4832 %} 4833 4834 operand flagsRegCR1() %{ 4835 constraint(ALLOC_IN_RC(int_flags_CR1)); 4836 match(RegFlags); 4837 format %{ "CR1" %} 4838 interface(REG_INTER); 4839 %} 4840 4841 operand flagsRegCR6() %{ 4842 constraint(ALLOC_IN_RC(int_flags_CR6)); 4843 match(RegFlags); 4844 format %{ "CR6" %} 4845 interface(REG_INTER); 4846 %} 4847 4848 operand regCTR() %{ 4849 constraint(ALLOC_IN_RC(ctr_reg)); 4850 // RegFlags should work. Introducing a RegSpecial type would cause a 4851 // lot of changes. 4852 match(RegFlags); 4853 format %{"SR_CTR" %} 4854 interface(REG_INTER); 4855 %} 4856 4857 operand regD() %{ 4858 constraint(ALLOC_IN_RC(dbl_reg)); 4859 match(RegD); 4860 format %{ %} 4861 interface(REG_INTER); 4862 %} 4863 4864 operand regF() %{ 4865 constraint(ALLOC_IN_RC(flt_reg)); 4866 match(RegF); 4867 format %{ %} 4868 interface(REG_INTER); 4869 %} 4870 4871 // Special Registers 4872 4873 // Method Register 4874 operand inline_cache_regP(iRegPdst reg) %{ 4875 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4876 match(reg); 4877 format %{ %} 4878 interface(REG_INTER); 4879 %} 4880 4881 operand compiler_method_oop_regP(iRegPdst reg) %{ 4882 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4883 match(reg); 4884 format %{ %} 4885 interface(REG_INTER); 4886 %} 4887 4888 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4889 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4890 match(reg); 4891 format %{ %} 4892 interface(REG_INTER); 4893 %} 4894 4895 // Operands to remove register moves in unscaled mode. 4896 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4897 operand iRegP2N(iRegPsrc reg) %{ 4898 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4899 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4900 match(EncodeP reg); 4901 format %{ "$reg" %} 4902 interface(REG_INTER) 4903 %} 4904 4905 operand iRegN2P(iRegNsrc reg) %{ 4906 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4907 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4908 match(DecodeN reg); 4909 format %{ "$reg" %} 4910 interface(REG_INTER) 4911 %} 4912 4913 operand iRegN2P_klass(iRegNsrc reg) %{ 4914 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4915 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4916 match(DecodeNKlass reg); 4917 format %{ "$reg" %} 4918 interface(REG_INTER) 4919 %} 4920 4921 //----------Complex Operands--------------------------------------------------- 4922 // Indirect Memory Reference 4923 operand indirect(iRegPsrc reg) %{ 4924 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4925 match(reg); 4926 op_cost(100); 4927 format %{ "[$reg]" %} 4928 interface(MEMORY_INTER) %{ 4929 base($reg); 4930 index(0x0); 4931 scale(0x0); 4932 disp(0x0); 4933 %} 4934 %} 4935 4936 // Indirect with Offset 4937 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4938 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4939 match(AddP reg offset); 4940 op_cost(100); 4941 format %{ "[$reg + $offset]" %} 4942 interface(MEMORY_INTER) %{ 4943 base($reg); 4944 index(0x0); 4945 scale(0x0); 4946 disp($offset); 4947 %} 4948 %} 4949 4950 // Indirect with 4-aligned Offset 4951 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4952 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4953 match(AddP reg offset); 4954 op_cost(100); 4955 format %{ "[$reg + $offset]" %} 4956 interface(MEMORY_INTER) %{ 4957 base($reg); 4958 index(0x0); 4959 scale(0x0); 4960 disp($offset); 4961 %} 4962 %} 4963 4964 //----------Complex Operands for Compressed OOPs------------------------------- 4965 // Compressed OOPs with narrow_oop_shift == 0. 4966 4967 // Indirect Memory Reference, compressed OOP 4968 operand indirectNarrow(iRegNsrc reg) %{ 4969 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4970 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4971 match(DecodeN reg); 4972 op_cost(100); 4973 format %{ "[$reg]" %} 4974 interface(MEMORY_INTER) %{ 4975 base($reg); 4976 index(0x0); 4977 scale(0x0); 4978 disp(0x0); 4979 %} 4980 %} 4981 4982 operand indirectNarrow_klass(iRegNsrc reg) %{ 4983 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4984 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4985 match(DecodeNKlass reg); 4986 op_cost(100); 4987 format %{ "[$reg]" %} 4988 interface(MEMORY_INTER) %{ 4989 base($reg); 4990 index(0x0); 4991 scale(0x0); 4992 disp(0x0); 4993 %} 4994 %} 4995 4996 // Indirect with Offset, compressed OOP 4997 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4998 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4999 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5000 match(AddP (DecodeN reg) offset); 5001 op_cost(100); 5002 format %{ "[$reg + $offset]" %} 5003 interface(MEMORY_INTER) %{ 5004 base($reg); 5005 index(0x0); 5006 scale(0x0); 5007 disp($offset); 5008 %} 5009 %} 5010 5011 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5012 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5013 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5014 match(AddP (DecodeNKlass reg) offset); 5015 op_cost(100); 5016 format %{ "[$reg + $offset]" %} 5017 interface(MEMORY_INTER) %{ 5018 base($reg); 5019 index(0x0); 5020 scale(0x0); 5021 disp($offset); 5022 %} 5023 %} 5024 5025 // Indirect with 4-aligned Offset, compressed OOP 5026 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5027 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5028 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5029 match(AddP (DecodeN reg) offset); 5030 op_cost(100); 5031 format %{ "[$reg + $offset]" %} 5032 interface(MEMORY_INTER) %{ 5033 base($reg); 5034 index(0x0); 5035 scale(0x0); 5036 disp($offset); 5037 %} 5038 %} 5039 5040 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5041 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5042 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5043 match(AddP (DecodeNKlass reg) offset); 5044 op_cost(100); 5045 format %{ "[$reg + $offset]" %} 5046 interface(MEMORY_INTER) %{ 5047 base($reg); 5048 index(0x0); 5049 scale(0x0); 5050 disp($offset); 5051 %} 5052 %} 5053 5054 //----------Special Memory Operands-------------------------------------------- 5055 // Stack Slot Operand 5056 // 5057 // This operand is used for loading and storing temporary values on 5058 // the stack where a match requires a value to flow through memory. 5059 operand stackSlotI(sRegI reg) %{ 5060 constraint(ALLOC_IN_RC(stack_slots)); 5061 op_cost(100); 5062 //match(RegI); 5063 format %{ "[sp+$reg]" %} 5064 interface(MEMORY_INTER) %{ 5065 base(0x1); // R1_SP 5066 index(0x0); 5067 scale(0x0); 5068 disp($reg); // Stack Offset 5069 %} 5070 %} 5071 5072 operand stackSlotL(sRegL reg) %{ 5073 constraint(ALLOC_IN_RC(stack_slots)); 5074 op_cost(100); 5075 //match(RegL); 5076 format %{ "[sp+$reg]" %} 5077 interface(MEMORY_INTER) %{ 5078 base(0x1); // R1_SP 5079 index(0x0); 5080 scale(0x0); 5081 disp($reg); // Stack Offset 5082 %} 5083 %} 5084 5085 operand stackSlotP(sRegP reg) %{ 5086 constraint(ALLOC_IN_RC(stack_slots)); 5087 op_cost(100); 5088 //match(RegP); 5089 format %{ "[sp+$reg]" %} 5090 interface(MEMORY_INTER) %{ 5091 base(0x1); // R1_SP 5092 index(0x0); 5093 scale(0x0); 5094 disp($reg); // Stack Offset 5095 %} 5096 %} 5097 5098 operand stackSlotF(sRegF reg) %{ 5099 constraint(ALLOC_IN_RC(stack_slots)); 5100 op_cost(100); 5101 //match(RegF); 5102 format %{ "[sp+$reg]" %} 5103 interface(MEMORY_INTER) %{ 5104 base(0x1); // R1_SP 5105 index(0x0); 5106 scale(0x0); 5107 disp($reg); // Stack Offset 5108 %} 5109 %} 5110 5111 operand stackSlotD(sRegD reg) %{ 5112 constraint(ALLOC_IN_RC(stack_slots)); 5113 op_cost(100); 5114 //match(RegD); 5115 format %{ "[sp+$reg]" %} 5116 interface(MEMORY_INTER) %{ 5117 base(0x1); // R1_SP 5118 index(0x0); 5119 scale(0x0); 5120 disp($reg); // Stack Offset 5121 %} 5122 %} 5123 5124 // Operands for expressing Control Flow 5125 // NOTE: Label is a predefined operand which should not be redefined in 5126 // the AD file. It is generically handled within the ADLC. 5127 5128 //----------Conditional Branch Operands---------------------------------------- 5129 // Comparison Op 5130 // 5131 // This is the operation of the comparison, and is limited to the 5132 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5133 // (!=). 5134 // 5135 // Other attributes of the comparison, such as unsignedness, are specified 5136 // by the comparison instruction that sets a condition code flags register. 5137 // That result is represented by a flags operand whose subtype is appropriate 5138 // to the unsignedness (etc.) of the comparison. 5139 // 5140 // Later, the instruction which matches both the Comparison Op (a Bool) and 5141 // the flags (produced by the Cmp) specifies the coding of the comparison op 5142 // by matching a specific subtype of Bool operand below. 5143 5144 // When used for floating point comparisons: unordered same as less. 5145 operand cmpOp() %{ 5146 match(Bool); 5147 format %{ "" %} 5148 interface(COND_INTER) %{ 5149 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5150 // BO & BI 5151 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5152 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5153 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5154 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5155 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5156 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5157 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5158 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5159 %} 5160 %} 5161 5162 //----------OPERAND CLASSES---------------------------------------------------- 5163 // Operand Classes are groups of operands that are used to simplify 5164 // instruction definitions by not requiring the AD writer to specify 5165 // seperate instructions for every form of operand when the 5166 // instruction accepts multiple operand types with the same basic 5167 // encoding and format. The classic case of this is memory operands. 5168 // Indirect is not included since its use is limited to Compare & Swap. 5169 5170 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5171 // Memory operand where offsets are 4-aligned. Required for ld, std. 5172 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5173 opclass indirectMemory(indirect, indirectNarrow); 5174 5175 // Special opclass for I and ConvL2I. 5176 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5177 5178 // Operand classes to match encode and decode. iRegN_P2N is only used 5179 // for storeN. I have never seen an encode node elsewhere. 5180 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5181 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5182 5183 //----------PIPELINE----------------------------------------------------------- 5184 5185 pipeline %{ 5186 5187 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5188 // J. Res. & Dev., No. 1, Jan. 2002. 5189 5190 //----------ATTRIBUTES--------------------------------------------------------- 5191 attributes %{ 5192 5193 // Power4 instructions are of fixed length. 5194 fixed_size_instructions; 5195 5196 // TODO: if `bundle' means number of instructions fetched 5197 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5198 // max instructions issued per cycle, this is 5. 5199 max_instructions_per_bundle = 8; 5200 5201 // A Power4 instruction is 4 bytes long. 5202 instruction_unit_size = 4; 5203 5204 // The Power4 processor fetches 64 bytes... 5205 instruction_fetch_unit_size = 64; 5206 5207 // ...in one line 5208 instruction_fetch_units = 1 5209 5210 // Unused, list one so that array generated by adlc is not empty. 5211 // Aix compiler chokes if _nop_count = 0. 5212 nops(fxNop); 5213 %} 5214 5215 //----------RESOURCES---------------------------------------------------------- 5216 // Resources are the functional units available to the machine 5217 resources( 5218 PPC_BR, // branch unit 5219 PPC_CR, // condition unit 5220 PPC_FX1, // integer arithmetic unit 1 5221 PPC_FX2, // integer arithmetic unit 2 5222 PPC_LDST1, // load/store unit 1 5223 PPC_LDST2, // load/store unit 2 5224 PPC_FP1, // float arithmetic unit 1 5225 PPC_FP2, // float arithmetic unit 2 5226 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5227 PPC_FX = PPC_FX1 | PPC_FX2, 5228 PPC_FP = PPC_FP1 | PPC_FP2 5229 ); 5230 5231 //----------PIPELINE DESCRIPTION----------------------------------------------- 5232 // Pipeline Description specifies the stages in the machine's pipeline 5233 pipe_desc( 5234 // Power4 longest pipeline path 5235 PPC_IF, // instruction fetch 5236 PPC_IC, 5237 //PPC_BP, // branch prediction 5238 PPC_D0, // decode 5239 PPC_D1, // decode 5240 PPC_D2, // decode 5241 PPC_D3, // decode 5242 PPC_Xfer1, 5243 PPC_GD, // group definition 5244 PPC_MP, // map 5245 PPC_ISS, // issue 5246 PPC_RF, // resource fetch 5247 PPC_EX1, // execute (all units) 5248 PPC_EX2, // execute (FP, LDST) 5249 PPC_EX3, // execute (FP, LDST) 5250 PPC_EX4, // execute (FP) 5251 PPC_EX5, // execute (FP) 5252 PPC_EX6, // execute (FP) 5253 PPC_WB, // write back 5254 PPC_Xfer2, 5255 PPC_CP 5256 ); 5257 5258 //----------PIPELINE CLASSES--------------------------------------------------- 5259 // Pipeline Classes describe the stages in which input and output are 5260 // referenced by the hardware pipeline. 5261 5262 // Simple pipeline classes. 5263 5264 // Default pipeline class. 5265 pipe_class pipe_class_default() %{ 5266 single_instruction; 5267 fixed_latency(2); 5268 %} 5269 5270 // Pipeline class for empty instructions. 5271 pipe_class pipe_class_empty() %{ 5272 single_instruction; 5273 fixed_latency(0); 5274 %} 5275 5276 // Pipeline class for compares. 5277 pipe_class pipe_class_compare() %{ 5278 single_instruction; 5279 fixed_latency(16); 5280 %} 5281 5282 // Pipeline class for traps. 5283 pipe_class pipe_class_trap() %{ 5284 single_instruction; 5285 fixed_latency(100); 5286 %} 5287 5288 // Pipeline class for memory operations. 5289 pipe_class pipe_class_memory() %{ 5290 single_instruction; 5291 fixed_latency(16); 5292 %} 5293 5294 // Pipeline class for call. 5295 pipe_class pipe_class_call() %{ 5296 single_instruction; 5297 fixed_latency(100); 5298 %} 5299 5300 // Define the class for the Nop node. 5301 define %{ 5302 MachNop = pipe_class_default; 5303 %} 5304 5305 %} 5306 5307 //----------INSTRUCTIONS------------------------------------------------------- 5308 5309 // Naming of instructions: 5310 // opA_operB / opA_operB_operC: 5311 // Operation 'op' with one or two source operands 'oper'. Result 5312 // type is A, source operand types are B and C. 5313 // Iff A == B == C, B and C are left out. 5314 // 5315 // The instructions are ordered according to the following scheme: 5316 // - loads 5317 // - load constants 5318 // - prefetch 5319 // - store 5320 // - encode/decode 5321 // - membar 5322 // - conditional moves 5323 // - compare & swap 5324 // - arithmetic and logic operations 5325 // * int: Add, Sub, Mul, Div, Mod 5326 // * int: lShift, arShift, urShift, rot 5327 // * float: Add, Sub, Mul, Div 5328 // * and, or, xor ... 5329 // - register moves: float <-> int, reg <-> stack, repl 5330 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5331 // - conv (low level type cast requiring bit changes (sign extend etc) 5332 // - compares, range & zero checks. 5333 // - branches 5334 // - complex operations, intrinsics, min, max, replicate 5335 // - lock 5336 // - Calls 5337 // 5338 // If there are similar instructions with different types they are sorted: 5339 // int before float 5340 // small before big 5341 // signed before unsigned 5342 // e.g., loadS before loadUS before loadI before loadF. 5343 5344 5345 //----------Load/Store Instructions-------------------------------------------- 5346 5347 //----------Load Instructions-------------------------------------------------- 5348 5349 // Converts byte to int. 5350 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5351 // reuses the 'amount' operand, but adlc expects that operand specification 5352 // and operands in match rule are equivalent. 5353 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5354 effect(DEF dst, USE src); 5355 format %{ "EXTSB $dst, $src \t// byte->int" %} 5356 size(4); 5357 ins_encode %{ 5358 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5359 __ extsb($dst$$Register, $src$$Register); 5360 %} 5361 ins_pipe(pipe_class_default); 5362 %} 5363 5364 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5365 // match-rule, false predicate 5366 match(Set dst (LoadB mem)); 5367 predicate(false); 5368 5369 format %{ "LBZ $dst, $mem" %} 5370 size(4); 5371 ins_encode( enc_lbz(dst, mem) ); 5372 ins_pipe(pipe_class_memory); 5373 %} 5374 5375 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5376 // match-rule, false predicate 5377 match(Set dst (LoadB mem)); 5378 predicate(false); 5379 5380 format %{ "LBZ $dst, $mem\n\t" 5381 "TWI $dst\n\t" 5382 "ISYNC" %} 5383 size(12); 5384 ins_encode( enc_lbz_ac(dst, mem) ); 5385 ins_pipe(pipe_class_memory); 5386 %} 5387 5388 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5389 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5390 match(Set dst (LoadB mem)); 5391 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5392 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5393 expand %{ 5394 iRegIdst tmp; 5395 loadUB_indirect(tmp, mem); 5396 convB2I_reg_2(dst, tmp); 5397 %} 5398 %} 5399 5400 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5401 match(Set dst (LoadB mem)); 5402 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5403 expand %{ 5404 iRegIdst tmp; 5405 loadUB_indirect_ac(tmp, mem); 5406 convB2I_reg_2(dst, tmp); 5407 %} 5408 %} 5409 5410 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5411 // match-rule, false predicate 5412 match(Set dst (LoadB mem)); 5413 predicate(false); 5414 5415 format %{ "LBZ $dst, $mem" %} 5416 size(4); 5417 ins_encode( enc_lbz(dst, mem) ); 5418 ins_pipe(pipe_class_memory); 5419 %} 5420 5421 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5422 // match-rule, false predicate 5423 match(Set dst (LoadB mem)); 5424 predicate(false); 5425 5426 format %{ "LBZ $dst, $mem\n\t" 5427 "TWI $dst\n\t" 5428 "ISYNC" %} 5429 size(12); 5430 ins_encode( enc_lbz_ac(dst, mem) ); 5431 ins_pipe(pipe_class_memory); 5432 %} 5433 5434 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5435 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5436 match(Set dst (LoadB mem)); 5437 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5438 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5439 5440 expand %{ 5441 iRegIdst tmp; 5442 loadUB_indOffset16(tmp, mem); 5443 convB2I_reg_2(dst, tmp); 5444 %} 5445 %} 5446 5447 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5448 match(Set dst (LoadB mem)); 5449 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5450 5451 expand %{ 5452 iRegIdst tmp; 5453 loadUB_indOffset16_ac(tmp, mem); 5454 convB2I_reg_2(dst, tmp); 5455 %} 5456 %} 5457 5458 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5459 instruct loadUB(iRegIdst dst, memory mem) %{ 5460 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5461 match(Set dst (LoadUB mem)); 5462 ins_cost(MEMORY_REF_COST); 5463 5464 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5465 size(4); 5466 ins_encode( enc_lbz(dst, mem) ); 5467 ins_pipe(pipe_class_memory); 5468 %} 5469 5470 // Load Unsigned Byte (8bit UNsigned) acquire. 5471 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5472 match(Set dst (LoadUB mem)); 5473 ins_cost(3*MEMORY_REF_COST); 5474 5475 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5476 "TWI $dst\n\t" 5477 "ISYNC" %} 5478 size(12); 5479 ins_encode( enc_lbz_ac(dst, mem) ); 5480 ins_pipe(pipe_class_memory); 5481 %} 5482 5483 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5484 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5485 match(Set dst (ConvI2L (LoadUB mem))); 5486 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5487 ins_cost(MEMORY_REF_COST); 5488 5489 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5490 size(4); 5491 ins_encode( enc_lbz(dst, mem) ); 5492 ins_pipe(pipe_class_memory); 5493 %} 5494 5495 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5496 match(Set dst (ConvI2L (LoadUB mem))); 5497 ins_cost(3*MEMORY_REF_COST); 5498 5499 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5500 "TWI $dst\n\t" 5501 "ISYNC" %} 5502 size(12); 5503 ins_encode( enc_lbz_ac(dst, mem) ); 5504 ins_pipe(pipe_class_memory); 5505 %} 5506 5507 // Load Short (16bit signed) 5508 instruct loadS(iRegIdst dst, memory mem) %{ 5509 match(Set dst (LoadS mem)); 5510 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5511 ins_cost(MEMORY_REF_COST); 5512 5513 format %{ "LHA $dst, $mem" %} 5514 size(4); 5515 ins_encode %{ 5516 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5517 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5518 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5519 %} 5520 ins_pipe(pipe_class_memory); 5521 %} 5522 5523 // Load Short (16bit signed) acquire. 5524 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5525 match(Set dst (LoadS mem)); 5526 ins_cost(3*MEMORY_REF_COST); 5527 5528 format %{ "LHA $dst, $mem\t acquire\n\t" 5529 "TWI $dst\n\t" 5530 "ISYNC" %} 5531 size(12); 5532 ins_encode %{ 5533 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5534 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5535 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5536 __ twi_0($dst$$Register); 5537 __ isync(); 5538 %} 5539 ins_pipe(pipe_class_memory); 5540 %} 5541 5542 // Load Char (16bit unsigned) 5543 instruct loadUS(iRegIdst dst, memory mem) %{ 5544 match(Set dst (LoadUS mem)); 5545 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5546 ins_cost(MEMORY_REF_COST); 5547 5548 format %{ "LHZ $dst, $mem" %} 5549 size(4); 5550 ins_encode( enc_lhz(dst, mem) ); 5551 ins_pipe(pipe_class_memory); 5552 %} 5553 5554 // Load Char (16bit unsigned) acquire. 5555 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5556 match(Set dst (LoadUS mem)); 5557 ins_cost(3*MEMORY_REF_COST); 5558 5559 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5560 "TWI $dst\n\t" 5561 "ISYNC" %} 5562 size(12); 5563 ins_encode( enc_lhz_ac(dst, mem) ); 5564 ins_pipe(pipe_class_memory); 5565 %} 5566 5567 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5568 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5569 match(Set dst (ConvI2L (LoadUS mem))); 5570 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5571 ins_cost(MEMORY_REF_COST); 5572 5573 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5574 size(4); 5575 ins_encode( enc_lhz(dst, mem) ); 5576 ins_pipe(pipe_class_memory); 5577 %} 5578 5579 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5580 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5581 match(Set dst (ConvI2L (LoadUS mem))); 5582 ins_cost(3*MEMORY_REF_COST); 5583 5584 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5585 "TWI $dst\n\t" 5586 "ISYNC" %} 5587 size(12); 5588 ins_encode( enc_lhz_ac(dst, mem) ); 5589 ins_pipe(pipe_class_memory); 5590 %} 5591 5592 // Load Integer. 5593 instruct loadI(iRegIdst dst, memory mem) %{ 5594 match(Set dst (LoadI mem)); 5595 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5596 ins_cost(MEMORY_REF_COST); 5597 5598 format %{ "LWZ $dst, $mem" %} 5599 size(4); 5600 ins_encode( enc_lwz(dst, mem) ); 5601 ins_pipe(pipe_class_memory); 5602 %} 5603 5604 // Load Integer acquire. 5605 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5606 match(Set dst (LoadI mem)); 5607 ins_cost(3*MEMORY_REF_COST); 5608 5609 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5610 "TWI $dst\n\t" 5611 "ISYNC" %} 5612 size(12); 5613 ins_encode( enc_lwz_ac(dst, mem) ); 5614 ins_pipe(pipe_class_memory); 5615 %} 5616 5617 // Match loading integer and casting it to unsigned int in 5618 // long register. 5619 // LoadI + ConvI2L + AndL 0xffffffff. 5620 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5621 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5622 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5623 ins_cost(MEMORY_REF_COST); 5624 5625 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5626 size(4); 5627 ins_encode( enc_lwz(dst, mem) ); 5628 ins_pipe(pipe_class_memory); 5629 %} 5630 5631 // Match loading integer and casting it to long. 5632 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5633 match(Set dst (ConvI2L (LoadI mem))); 5634 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5635 ins_cost(MEMORY_REF_COST); 5636 5637 format %{ "LWA $dst, $mem \t// loadI2L" %} 5638 size(4); 5639 ins_encode %{ 5640 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5641 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5642 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5643 %} 5644 ins_pipe(pipe_class_memory); 5645 %} 5646 5647 // Match loading integer and casting it to long - acquire. 5648 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5649 match(Set dst (ConvI2L (LoadI mem))); 5650 ins_cost(3*MEMORY_REF_COST); 5651 5652 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5653 "TWI $dst\n\t" 5654 "ISYNC" %} 5655 size(12); 5656 ins_encode %{ 5657 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5658 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5659 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5660 __ twi_0($dst$$Register); 5661 __ isync(); 5662 %} 5663 ins_pipe(pipe_class_memory); 5664 %} 5665 5666 // Load Long - aligned 5667 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5668 match(Set dst (LoadL mem)); 5669 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5670 ins_cost(MEMORY_REF_COST); 5671 5672 format %{ "LD $dst, $mem \t// long" %} 5673 size(4); 5674 ins_encode( enc_ld(dst, mem) ); 5675 ins_pipe(pipe_class_memory); 5676 %} 5677 5678 // Load Long - aligned acquire. 5679 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5680 match(Set dst (LoadL mem)); 5681 ins_cost(3*MEMORY_REF_COST); 5682 5683 format %{ "LD $dst, $mem \t// long acquire\n\t" 5684 "TWI $dst\n\t" 5685 "ISYNC" %} 5686 size(12); 5687 ins_encode( enc_ld_ac(dst, mem) ); 5688 ins_pipe(pipe_class_memory); 5689 %} 5690 5691 // Load Long - UNaligned 5692 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5693 match(Set dst (LoadL_unaligned mem)); 5694 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5695 ins_cost(MEMORY_REF_COST); 5696 5697 format %{ "LD $dst, $mem \t// unaligned long" %} 5698 size(4); 5699 ins_encode( enc_ld(dst, mem) ); 5700 ins_pipe(pipe_class_memory); 5701 %} 5702 5703 // Load nodes for superwords 5704 5705 // Load Aligned Packed Byte 5706 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5707 predicate(n->as_LoadVector()->memory_size() == 8); 5708 match(Set dst (LoadVector mem)); 5709 ins_cost(MEMORY_REF_COST); 5710 5711 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5712 size(4); 5713 ins_encode( enc_ld(dst, mem) ); 5714 ins_pipe(pipe_class_memory); 5715 %} 5716 5717 // Load Aligned Packed Byte 5718 instruct loadV16(vecX dst, indirect mem) %{ 5719 predicate(n->as_LoadVector()->memory_size() == 16); 5720 match(Set dst (LoadVector mem)); 5721 ins_cost(MEMORY_REF_COST); 5722 5723 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5724 size(4); 5725 ins_encode %{ 5726 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5727 %} 5728 ins_pipe(pipe_class_default); 5729 %} 5730 5731 // Load Range, range = array length (=jint) 5732 instruct loadRange(iRegIdst dst, memory mem) %{ 5733 match(Set dst (LoadRange mem)); 5734 ins_cost(MEMORY_REF_COST); 5735 5736 format %{ "LWZ $dst, $mem \t// range" %} 5737 size(4); 5738 ins_encode( enc_lwz(dst, mem) ); 5739 ins_pipe(pipe_class_memory); 5740 %} 5741 5742 // Load Compressed Pointer 5743 instruct loadN(iRegNdst dst, memory mem) %{ 5744 match(Set dst (LoadN mem)); 5745 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5746 ins_cost(MEMORY_REF_COST); 5747 5748 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5749 size(4); 5750 ins_encode( enc_lwz(dst, mem) ); 5751 ins_pipe(pipe_class_memory); 5752 %} 5753 5754 // Load Compressed Pointer acquire. 5755 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5756 match(Set dst (LoadN mem)); 5757 ins_cost(3*MEMORY_REF_COST); 5758 5759 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5760 "TWI $dst\n\t" 5761 "ISYNC" %} 5762 size(12); 5763 ins_encode( enc_lwz_ac(dst, mem) ); 5764 ins_pipe(pipe_class_memory); 5765 %} 5766 5767 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5768 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5769 match(Set dst (DecodeN (LoadN mem))); 5770 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5771 ins_cost(MEMORY_REF_COST); 5772 5773 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5774 size(4); 5775 ins_encode( enc_lwz(dst, mem) ); 5776 ins_pipe(pipe_class_memory); 5777 %} 5778 5779 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5780 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5781 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5782 _kids[0]->_leaf->as_Load()->is_unordered()); 5783 ins_cost(MEMORY_REF_COST); 5784 5785 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5786 size(4); 5787 ins_encode( enc_lwz(dst, mem) ); 5788 ins_pipe(pipe_class_memory); 5789 %} 5790 5791 // Load Pointer 5792 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5793 match(Set dst (LoadP mem)); 5794 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5795 ins_cost(MEMORY_REF_COST); 5796 5797 format %{ "LD $dst, $mem \t// ptr" %} 5798 size(4); 5799 ins_encode( enc_ld(dst, mem) ); 5800 ins_pipe(pipe_class_memory); 5801 %} 5802 5803 // Load Pointer acquire. 5804 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5805 match(Set dst (LoadP mem)); 5806 ins_cost(3*MEMORY_REF_COST); 5807 5808 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5809 "TWI $dst\n\t" 5810 "ISYNC" %} 5811 size(12); 5812 ins_encode( enc_ld_ac(dst, mem) ); 5813 ins_pipe(pipe_class_memory); 5814 %} 5815 5816 // LoadP + CastP2L 5817 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5818 match(Set dst (CastP2X (LoadP mem))); 5819 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5820 ins_cost(MEMORY_REF_COST); 5821 5822 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5823 size(4); 5824 ins_encode( enc_ld(dst, mem) ); 5825 ins_pipe(pipe_class_memory); 5826 %} 5827 5828 // Load compressed klass pointer. 5829 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5830 match(Set dst (LoadNKlass mem)); 5831 ins_cost(MEMORY_REF_COST); 5832 5833 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5834 size(4); 5835 ins_encode( enc_lwz(dst, mem) ); 5836 ins_pipe(pipe_class_memory); 5837 %} 5838 5839 // Load Klass Pointer 5840 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5841 match(Set dst (LoadKlass mem)); 5842 ins_cost(MEMORY_REF_COST); 5843 5844 format %{ "LD $dst, $mem \t// klass ptr" %} 5845 size(4); 5846 ins_encode( enc_ld(dst, mem) ); 5847 ins_pipe(pipe_class_memory); 5848 %} 5849 5850 // Load Float 5851 instruct loadF(regF dst, memory mem) %{ 5852 match(Set dst (LoadF mem)); 5853 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5854 ins_cost(MEMORY_REF_COST); 5855 5856 format %{ "LFS $dst, $mem" %} 5857 size(4); 5858 ins_encode %{ 5859 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5860 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5861 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5862 %} 5863 ins_pipe(pipe_class_memory); 5864 %} 5865 5866 // Load Float acquire. 5867 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5868 match(Set dst (LoadF mem)); 5869 effect(TEMP cr0); 5870 ins_cost(3*MEMORY_REF_COST); 5871 5872 format %{ "LFS $dst, $mem \t// acquire\n\t" 5873 "FCMPU cr0, $dst, $dst\n\t" 5874 "BNE cr0, next\n" 5875 "next:\n\t" 5876 "ISYNC" %} 5877 size(16); 5878 ins_encode %{ 5879 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5880 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5881 Label next; 5882 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5883 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5884 __ bne(CCR0, next); 5885 __ bind(next); 5886 __ isync(); 5887 %} 5888 ins_pipe(pipe_class_memory); 5889 %} 5890 5891 // Load Double - aligned 5892 instruct loadD(regD dst, memory mem) %{ 5893 match(Set dst (LoadD mem)); 5894 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5895 ins_cost(MEMORY_REF_COST); 5896 5897 format %{ "LFD $dst, $mem" %} 5898 size(4); 5899 ins_encode( enc_lfd(dst, mem) ); 5900 ins_pipe(pipe_class_memory); 5901 %} 5902 5903 // Load Double - aligned acquire. 5904 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5905 match(Set dst (LoadD mem)); 5906 effect(TEMP cr0); 5907 ins_cost(3*MEMORY_REF_COST); 5908 5909 format %{ "LFD $dst, $mem \t// acquire\n\t" 5910 "FCMPU cr0, $dst, $dst\n\t" 5911 "BNE cr0, next\n" 5912 "next:\n\t" 5913 "ISYNC" %} 5914 size(16); 5915 ins_encode %{ 5916 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5917 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5918 Label next; 5919 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5920 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5921 __ bne(CCR0, next); 5922 __ bind(next); 5923 __ isync(); 5924 %} 5925 ins_pipe(pipe_class_memory); 5926 %} 5927 5928 // Load Double - UNaligned 5929 instruct loadD_unaligned(regD dst, memory mem) %{ 5930 match(Set dst (LoadD_unaligned mem)); 5931 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5932 ins_cost(MEMORY_REF_COST); 5933 5934 format %{ "LFD $dst, $mem" %} 5935 size(4); 5936 ins_encode( enc_lfd(dst, mem) ); 5937 ins_pipe(pipe_class_memory); 5938 %} 5939 5940 //----------Constants-------------------------------------------------------- 5941 5942 // Load MachConstantTableBase: add hi offset to global toc. 5943 // TODO: Handle hidden register r29 in bundler! 5944 instruct loadToc_hi(iRegLdst dst) %{ 5945 effect(DEF dst); 5946 ins_cost(DEFAULT_COST); 5947 5948 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5949 size(4); 5950 ins_encode %{ 5951 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5952 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5953 %} 5954 ins_pipe(pipe_class_default); 5955 %} 5956 5957 // Load MachConstantTableBase: add lo offset to global toc. 5958 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5959 effect(DEF dst, USE src); 5960 ins_cost(DEFAULT_COST); 5961 5962 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5963 size(4); 5964 ins_encode %{ 5965 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5966 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5967 %} 5968 ins_pipe(pipe_class_default); 5969 %} 5970 5971 // Load 16-bit integer constant 0xssss???? 5972 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5973 match(Set dst src); 5974 5975 format %{ "LI $dst, $src" %} 5976 size(4); 5977 ins_encode %{ 5978 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5979 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5980 %} 5981 ins_pipe(pipe_class_default); 5982 %} 5983 5984 // Load integer constant 0x????0000 5985 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5986 match(Set dst src); 5987 ins_cost(DEFAULT_COST); 5988 5989 format %{ "LIS $dst, $src.hi" %} 5990 size(4); 5991 ins_encode %{ 5992 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5993 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5994 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5995 %} 5996 ins_pipe(pipe_class_default); 5997 %} 5998 5999 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6000 // and sign extended), this adds the low 16 bits. 6001 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6002 // no match-rule, false predicate 6003 effect(DEF dst, USE src1, USE src2); 6004 predicate(false); 6005 6006 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6007 size(4); 6008 ins_encode %{ 6009 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6010 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6011 %} 6012 ins_pipe(pipe_class_default); 6013 %} 6014 6015 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6016 match(Set dst src); 6017 ins_cost(DEFAULT_COST*2); 6018 6019 expand %{ 6020 // Would like to use $src$$constant. 6021 immI16 srcLo %{ _opnds[1]->constant() %} 6022 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6023 immIhi16 srcHi %{ _opnds[1]->constant() %} 6024 iRegIdst tmpI; 6025 loadConIhi16(tmpI, srcHi); 6026 loadConI32_lo16(dst, tmpI, srcLo); 6027 %} 6028 %} 6029 6030 // No constant pool entries required. 6031 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6032 match(Set dst src); 6033 6034 format %{ "LI $dst, $src \t// long" %} 6035 size(4); 6036 ins_encode %{ 6037 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6038 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6039 %} 6040 ins_pipe(pipe_class_default); 6041 %} 6042 6043 // Load long constant 0xssssssss????0000 6044 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6045 match(Set dst src); 6046 ins_cost(DEFAULT_COST); 6047 6048 format %{ "LIS $dst, $src.hi \t// long" %} 6049 size(4); 6050 ins_encode %{ 6051 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6052 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6053 %} 6054 ins_pipe(pipe_class_default); 6055 %} 6056 6057 // To load a 32 bit constant: merge lower 16 bits into already loaded 6058 // high 16 bits. 6059 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6060 // no match-rule, false predicate 6061 effect(DEF dst, USE src1, USE src2); 6062 predicate(false); 6063 6064 format %{ "ORI $dst, $src1, $src2.lo" %} 6065 size(4); 6066 ins_encode %{ 6067 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6068 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6069 %} 6070 ins_pipe(pipe_class_default); 6071 %} 6072 6073 // Load 32-bit long constant 6074 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6075 match(Set dst src); 6076 ins_cost(DEFAULT_COST*2); 6077 6078 expand %{ 6079 // Would like to use $src$$constant. 6080 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6081 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6082 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6083 iRegLdst tmpL; 6084 loadConL32hi16(tmpL, srcHi); 6085 loadConL32_lo16(dst, tmpL, srcLo); 6086 %} 6087 %} 6088 6089 // Load long constant 0x????000000000000. 6090 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6091 match(Set dst src); 6092 ins_cost(DEFAULT_COST); 6093 6094 expand %{ 6095 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6096 immI shift32 %{ 32 %} 6097 iRegLdst tmpL; 6098 loadConL32hi16(tmpL, srcHi); 6099 lshiftL_regL_immI(dst, tmpL, shift32); 6100 %} 6101 %} 6102 6103 // Expand node for constant pool load: small offset. 6104 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6105 effect(DEF dst, USE src, USE toc); 6106 ins_cost(MEMORY_REF_COST); 6107 6108 ins_num_consts(1); 6109 // Needed so that CallDynamicJavaDirect can compute the address of this 6110 // instruction for relocation. 6111 ins_field_cbuf_insts_offset(int); 6112 6113 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6114 size(4); 6115 ins_encode( enc_load_long_constL(dst, src, toc) ); 6116 ins_pipe(pipe_class_memory); 6117 %} 6118 6119 // Expand node for constant pool load: large offset. 6120 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6121 effect(DEF dst, USE src, USE toc); 6122 predicate(false); 6123 6124 ins_num_consts(1); 6125 ins_field_const_toc_offset(int); 6126 // Needed so that CallDynamicJavaDirect can compute the address of this 6127 // instruction for relocation. 6128 ins_field_cbuf_insts_offset(int); 6129 6130 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6131 size(4); 6132 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6133 ins_pipe(pipe_class_default); 6134 %} 6135 6136 // Expand node for constant pool load: large offset. 6137 // No constant pool entries required. 6138 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6139 effect(DEF dst, USE src, USE base); 6140 predicate(false); 6141 6142 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6143 6144 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6145 size(4); 6146 ins_encode %{ 6147 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6148 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6149 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6150 %} 6151 ins_pipe(pipe_class_memory); 6152 %} 6153 6154 // Load long constant from constant table. Expand in case of 6155 // offset > 16 bit is needed. 6156 // Adlc adds toc node MachConstantTableBase. 6157 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6158 match(Set dst src); 6159 ins_cost(MEMORY_REF_COST); 6160 6161 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6162 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6163 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6164 %} 6165 6166 // Load NULL as compressed oop. 6167 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6168 match(Set dst src); 6169 ins_cost(DEFAULT_COST); 6170 6171 format %{ "LI $dst, $src \t// compressed ptr" %} 6172 size(4); 6173 ins_encode %{ 6174 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6175 __ li($dst$$Register, 0); 6176 %} 6177 ins_pipe(pipe_class_default); 6178 %} 6179 6180 // Load hi part of compressed oop constant. 6181 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6182 effect(DEF dst, USE src); 6183 ins_cost(DEFAULT_COST); 6184 6185 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6186 size(4); 6187 ins_encode %{ 6188 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6189 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6190 %} 6191 ins_pipe(pipe_class_default); 6192 %} 6193 6194 // Add lo part of compressed oop constant to already loaded hi part. 6195 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6196 effect(DEF dst, USE src1, USE src2); 6197 ins_cost(DEFAULT_COST); 6198 6199 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6200 size(4); 6201 ins_encode %{ 6202 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6203 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6204 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6205 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6206 __ relocate(rspec, 1); 6207 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6208 %} 6209 ins_pipe(pipe_class_default); 6210 %} 6211 6212 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6213 effect(DEF dst, USE src, USE shift, USE mask_begin); 6214 6215 size(4); 6216 ins_encode %{ 6217 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6218 %} 6219 ins_pipe(pipe_class_default); 6220 %} 6221 6222 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6223 // leaving the upper 32 bits with sign-extension bits. 6224 // This clears these bits: dst = src & 0xFFFFFFFF. 6225 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6226 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6227 effect(DEF dst, USE src); 6228 predicate(false); 6229 6230 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6231 size(4); 6232 ins_encode %{ 6233 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6234 __ clrldi($dst$$Register, $src$$Register, 0x20); 6235 %} 6236 ins_pipe(pipe_class_default); 6237 %} 6238 6239 // Optimize DecodeN for disjoint base. 6240 // Load base of compressed oops into a register 6241 instruct loadBase(iRegLdst dst) %{ 6242 effect(DEF dst); 6243 6244 format %{ "LoadConst $dst, heapbase" %} 6245 ins_encode %{ 6246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6247 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6248 %} 6249 ins_pipe(pipe_class_default); 6250 %} 6251 6252 // Loading ConN must be postalloc expanded so that edges between 6253 // the nodes are safe. They may not interfere with a safepoint. 6254 // GL TODO: This needs three instructions: better put this into the constant pool. 6255 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6256 match(Set dst src); 6257 ins_cost(DEFAULT_COST*2); 6258 6259 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6260 postalloc_expand %{ 6261 MachNode *m1 = new loadConN_hiNode(); 6262 MachNode *m2 = new loadConN_loNode(); 6263 MachNode *m3 = new clearMs32bNode(); 6264 m1->add_req(NULL); 6265 m2->add_req(NULL, m1); 6266 m3->add_req(NULL, m2); 6267 m1->_opnds[0] = op_dst; 6268 m1->_opnds[1] = op_src; 6269 m2->_opnds[0] = op_dst; 6270 m2->_opnds[1] = op_dst; 6271 m2->_opnds[2] = op_src; 6272 m3->_opnds[0] = op_dst; 6273 m3->_opnds[1] = op_dst; 6274 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6275 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6276 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6277 nodes->push(m1); 6278 nodes->push(m2); 6279 nodes->push(m3); 6280 %} 6281 %} 6282 6283 // We have seen a safepoint between the hi and lo parts, and this node was handled 6284 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6285 // not a narrow oop. 6286 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6287 match(Set dst src); 6288 effect(DEF dst, USE src); 6289 ins_cost(DEFAULT_COST); 6290 6291 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6292 size(4); 6293 ins_encode %{ 6294 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6295 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6296 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6297 %} 6298 ins_pipe(pipe_class_default); 6299 %} 6300 6301 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6302 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6303 match(Set dst src1); 6304 effect(TEMP src2); 6305 ins_cost(DEFAULT_COST); 6306 6307 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6308 size(4); 6309 ins_encode %{ 6310 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6311 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6312 %} 6313 ins_pipe(pipe_class_default); 6314 %} 6315 6316 // This needs a match rule so that build_oop_map knows this is 6317 // not a narrow oop. 6318 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6319 match(Set dst src1); 6320 effect(TEMP src2); 6321 ins_cost(DEFAULT_COST); 6322 6323 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6324 size(4); 6325 ins_encode %{ 6326 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6327 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6328 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6329 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6330 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6331 6332 __ relocate(rspec, 1); 6333 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6334 %} 6335 ins_pipe(pipe_class_default); 6336 %} 6337 6338 // Loading ConNKlass must be postalloc expanded so that edges between 6339 // the nodes are safe. They may not interfere with a safepoint. 6340 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6341 match(Set dst src); 6342 ins_cost(DEFAULT_COST*2); 6343 6344 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6345 postalloc_expand %{ 6346 // Load high bits into register. Sign extended. 6347 MachNode *m1 = new loadConNKlass_hiNode(); 6348 m1->add_req(NULL); 6349 m1->_opnds[0] = op_dst; 6350 m1->_opnds[1] = op_src; 6351 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6352 nodes->push(m1); 6353 6354 MachNode *m2 = m1; 6355 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6356 // Value might be 1-extended. Mask out these bits. 6357 m2 = new loadConNKlass_maskNode(); 6358 m2->add_req(NULL, m1); 6359 m2->_opnds[0] = op_dst; 6360 m2->_opnds[1] = op_src; 6361 m2->_opnds[2] = op_dst; 6362 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6363 nodes->push(m2); 6364 } 6365 6366 MachNode *m3 = new loadConNKlass_loNode(); 6367 m3->add_req(NULL, m2); 6368 m3->_opnds[0] = op_dst; 6369 m3->_opnds[1] = op_src; 6370 m3->_opnds[2] = op_dst; 6371 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6372 nodes->push(m3); 6373 %} 6374 %} 6375 6376 // 0x1 is used in object initialization (initial object header). 6377 // No constant pool entries required. 6378 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6379 match(Set dst src); 6380 6381 format %{ "LI $dst, $src \t// ptr" %} 6382 size(4); 6383 ins_encode %{ 6384 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6385 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6386 %} 6387 ins_pipe(pipe_class_default); 6388 %} 6389 6390 // Expand node for constant pool load: small offset. 6391 // The match rule is needed to generate the correct bottom_type(), 6392 // however this node should never match. The use of predicate is not 6393 // possible since ADLC forbids predicates for chain rules. The higher 6394 // costs do not prevent matching in this case. For that reason the 6395 // operand immP_NM with predicate(false) is used. 6396 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6397 match(Set dst src); 6398 effect(TEMP toc); 6399 6400 ins_num_consts(1); 6401 6402 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6403 size(4); 6404 ins_encode( enc_load_long_constP(dst, src, toc) ); 6405 ins_pipe(pipe_class_memory); 6406 %} 6407 6408 // Expand node for constant pool load: large offset. 6409 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6410 effect(DEF dst, USE src, USE toc); 6411 predicate(false); 6412 6413 ins_num_consts(1); 6414 ins_field_const_toc_offset(int); 6415 6416 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6417 size(4); 6418 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6419 ins_pipe(pipe_class_default); 6420 %} 6421 6422 // Expand node for constant pool load: large offset. 6423 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6424 match(Set dst src); 6425 effect(TEMP base); 6426 6427 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6428 6429 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6430 size(4); 6431 ins_encode %{ 6432 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6433 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6434 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6435 %} 6436 ins_pipe(pipe_class_memory); 6437 %} 6438 6439 // Load pointer constant from constant table. Expand in case an 6440 // offset > 16 bit is needed. 6441 // Adlc adds toc node MachConstantTableBase. 6442 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6443 match(Set dst src); 6444 ins_cost(MEMORY_REF_COST); 6445 6446 // This rule does not use "expand" because then 6447 // the result type is not known to be an Oop. An ADLC 6448 // enhancement will be needed to make that work - not worth it! 6449 6450 // If this instruction rematerializes, it prolongs the live range 6451 // of the toc node, causing illegal graphs. 6452 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6453 ins_cannot_rematerialize(true); 6454 6455 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6456 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6457 %} 6458 6459 // Expand node for constant pool load: small offset. 6460 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6461 effect(DEF dst, USE src, USE toc); 6462 ins_cost(MEMORY_REF_COST); 6463 6464 ins_num_consts(1); 6465 6466 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6467 size(4); 6468 ins_encode %{ 6469 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6470 address float_address = __ float_constant($src$$constant); 6471 if (float_address == NULL) { 6472 ciEnv::current()->record_out_of_memory_failure(); 6473 return; 6474 } 6475 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6476 %} 6477 ins_pipe(pipe_class_memory); 6478 %} 6479 6480 // Expand node for constant pool load: large offset. 6481 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6482 effect(DEF dst, USE src, USE toc); 6483 ins_cost(MEMORY_REF_COST); 6484 6485 ins_num_consts(1); 6486 6487 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6488 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6489 "ADDIS $toc, $toc, -offset_hi"%} 6490 size(12); 6491 ins_encode %{ 6492 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6493 FloatRegister Rdst = $dst$$FloatRegister; 6494 Register Rtoc = $toc$$Register; 6495 address float_address = __ float_constant($src$$constant); 6496 if (float_address == NULL) { 6497 ciEnv::current()->record_out_of_memory_failure(); 6498 return; 6499 } 6500 int offset = __ offset_to_method_toc(float_address); 6501 int hi = (offset + (1<<15))>>16; 6502 int lo = offset - hi * (1<<16); 6503 6504 __ addis(Rtoc, Rtoc, hi); 6505 __ lfs(Rdst, lo, Rtoc); 6506 __ addis(Rtoc, Rtoc, -hi); 6507 %} 6508 ins_pipe(pipe_class_memory); 6509 %} 6510 6511 // Adlc adds toc node MachConstantTableBase. 6512 instruct loadConF_Ex(regF dst, immF src) %{ 6513 match(Set dst src); 6514 ins_cost(MEMORY_REF_COST); 6515 6516 // See loadConP. 6517 ins_cannot_rematerialize(true); 6518 6519 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6520 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6521 %} 6522 6523 // Expand node for constant pool load: small offset. 6524 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6525 effect(DEF dst, USE src, USE toc); 6526 ins_cost(MEMORY_REF_COST); 6527 6528 ins_num_consts(1); 6529 6530 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6531 size(4); 6532 ins_encode %{ 6533 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6534 address float_address = __ double_constant($src$$constant); 6535 if (float_address == NULL) { 6536 ciEnv::current()->record_out_of_memory_failure(); 6537 return; 6538 } 6539 int offset = __ offset_to_method_toc(float_address); 6540 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6541 %} 6542 ins_pipe(pipe_class_memory); 6543 %} 6544 6545 // Expand node for constant pool load: large offset. 6546 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6547 effect(DEF dst, USE src, USE toc); 6548 ins_cost(MEMORY_REF_COST); 6549 6550 ins_num_consts(1); 6551 6552 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6553 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6554 "ADDIS $toc, $toc, -offset_hi" %} 6555 size(12); 6556 ins_encode %{ 6557 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6558 FloatRegister Rdst = $dst$$FloatRegister; 6559 Register Rtoc = $toc$$Register; 6560 address float_address = __ double_constant($src$$constant); 6561 if (float_address == NULL) { 6562 ciEnv::current()->record_out_of_memory_failure(); 6563 return; 6564 } 6565 int offset = __ offset_to_method_toc(float_address); 6566 int hi = (offset + (1<<15))>>16; 6567 int lo = offset - hi * (1<<16); 6568 6569 __ addis(Rtoc, Rtoc, hi); 6570 __ lfd(Rdst, lo, Rtoc); 6571 __ addis(Rtoc, Rtoc, -hi); 6572 %} 6573 ins_pipe(pipe_class_memory); 6574 %} 6575 6576 // Adlc adds toc node MachConstantTableBase. 6577 instruct loadConD_Ex(regD dst, immD src) %{ 6578 match(Set dst src); 6579 ins_cost(MEMORY_REF_COST); 6580 6581 // See loadConP. 6582 ins_cannot_rematerialize(true); 6583 6584 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6585 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6586 %} 6587 6588 // Prefetch instructions. 6589 // Must be safe to execute with invalid address (cannot fault). 6590 6591 // Special prefetch versions which use the dcbz instruction. 6592 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6593 match(PrefetchAllocation (AddP mem src)); 6594 predicate(AllocatePrefetchStyle == 3); 6595 ins_cost(MEMORY_REF_COST); 6596 6597 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6598 size(4); 6599 ins_encode %{ 6600 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6601 __ dcbz($src$$Register, $mem$$base$$Register); 6602 %} 6603 ins_pipe(pipe_class_memory); 6604 %} 6605 6606 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6607 match(PrefetchAllocation mem); 6608 predicate(AllocatePrefetchStyle == 3); 6609 ins_cost(MEMORY_REF_COST); 6610 6611 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6612 size(4); 6613 ins_encode %{ 6614 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6615 __ dcbz($mem$$base$$Register); 6616 %} 6617 ins_pipe(pipe_class_memory); 6618 %} 6619 6620 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6621 match(PrefetchAllocation (AddP mem src)); 6622 predicate(AllocatePrefetchStyle != 3); 6623 ins_cost(MEMORY_REF_COST); 6624 6625 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6626 size(4); 6627 ins_encode %{ 6628 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6629 __ dcbtst($src$$Register, $mem$$base$$Register); 6630 %} 6631 ins_pipe(pipe_class_memory); 6632 %} 6633 6634 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6635 match(PrefetchAllocation mem); 6636 predicate(AllocatePrefetchStyle != 3); 6637 ins_cost(MEMORY_REF_COST); 6638 6639 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6640 size(4); 6641 ins_encode %{ 6642 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6643 __ dcbtst($mem$$base$$Register); 6644 %} 6645 ins_pipe(pipe_class_memory); 6646 %} 6647 6648 //----------Store Instructions------------------------------------------------- 6649 6650 // Store Byte 6651 instruct storeB(memory mem, iRegIsrc src) %{ 6652 match(Set mem (StoreB mem src)); 6653 ins_cost(MEMORY_REF_COST); 6654 6655 format %{ "STB $src, $mem \t// byte" %} 6656 size(4); 6657 ins_encode %{ 6658 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6659 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6660 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6661 %} 6662 ins_pipe(pipe_class_memory); 6663 %} 6664 6665 // Store Char/Short 6666 instruct storeC(memory mem, iRegIsrc src) %{ 6667 match(Set mem (StoreC mem src)); 6668 ins_cost(MEMORY_REF_COST); 6669 6670 format %{ "STH $src, $mem \t// short" %} 6671 size(4); 6672 ins_encode %{ 6673 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6674 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6675 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6676 %} 6677 ins_pipe(pipe_class_memory); 6678 %} 6679 6680 // Store Integer 6681 instruct storeI(memory mem, iRegIsrc src) %{ 6682 match(Set mem (StoreI mem src)); 6683 ins_cost(MEMORY_REF_COST); 6684 6685 format %{ "STW $src, $mem" %} 6686 size(4); 6687 ins_encode( enc_stw(src, mem) ); 6688 ins_pipe(pipe_class_memory); 6689 %} 6690 6691 // ConvL2I + StoreI. 6692 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6693 match(Set mem (StoreI mem (ConvL2I src))); 6694 ins_cost(MEMORY_REF_COST); 6695 6696 format %{ "STW l2i($src), $mem" %} 6697 size(4); 6698 ins_encode( enc_stw(src, mem) ); 6699 ins_pipe(pipe_class_memory); 6700 %} 6701 6702 // Store Long 6703 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6704 match(Set mem (StoreL mem src)); 6705 ins_cost(MEMORY_REF_COST); 6706 6707 format %{ "STD $src, $mem \t// long" %} 6708 size(4); 6709 ins_encode( enc_std(src, mem) ); 6710 ins_pipe(pipe_class_memory); 6711 %} 6712 6713 // Store super word nodes. 6714 6715 // Store Aligned Packed Byte long register to memory 6716 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6717 predicate(n->as_StoreVector()->memory_size() == 8); 6718 match(Set mem (StoreVector mem src)); 6719 ins_cost(MEMORY_REF_COST); 6720 6721 format %{ "STD $mem, $src \t// packed8B" %} 6722 size(4); 6723 ins_encode( enc_std(src, mem) ); 6724 ins_pipe(pipe_class_memory); 6725 %} 6726 6727 // Store Packed Byte long register to memory 6728 instruct storeV16(indirect mem, vecX src) %{ 6729 predicate(n->as_StoreVector()->memory_size() == 16); 6730 match(Set mem (StoreVector mem src)); 6731 ins_cost(MEMORY_REF_COST); 6732 6733 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6734 size(4); 6735 ins_encode %{ 6736 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6737 %} 6738 ins_pipe(pipe_class_default); 6739 %} 6740 6741 // Store Compressed Oop 6742 instruct storeN(memory dst, iRegN_P2N src) %{ 6743 match(Set dst (StoreN dst src)); 6744 ins_cost(MEMORY_REF_COST); 6745 6746 format %{ "STW $src, $dst \t// compressed oop" %} 6747 size(4); 6748 ins_encode( enc_stw(src, dst) ); 6749 ins_pipe(pipe_class_memory); 6750 %} 6751 6752 // Store Compressed KLass 6753 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6754 match(Set dst (StoreNKlass dst src)); 6755 ins_cost(MEMORY_REF_COST); 6756 6757 format %{ "STW $src, $dst \t// compressed klass" %} 6758 size(4); 6759 ins_encode( enc_stw(src, dst) ); 6760 ins_pipe(pipe_class_memory); 6761 %} 6762 6763 // Store Pointer 6764 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6765 match(Set dst (StoreP dst src)); 6766 ins_cost(MEMORY_REF_COST); 6767 6768 format %{ "STD $src, $dst \t// ptr" %} 6769 size(4); 6770 ins_encode( enc_std(src, dst) ); 6771 ins_pipe(pipe_class_memory); 6772 %} 6773 6774 // Store Float 6775 instruct storeF(memory mem, regF src) %{ 6776 match(Set mem (StoreF mem src)); 6777 ins_cost(MEMORY_REF_COST); 6778 6779 format %{ "STFS $src, $mem" %} 6780 size(4); 6781 ins_encode( enc_stfs(src, mem) ); 6782 ins_pipe(pipe_class_memory); 6783 %} 6784 6785 // Store Double 6786 instruct storeD(memory mem, regD src) %{ 6787 match(Set mem (StoreD mem src)); 6788 ins_cost(MEMORY_REF_COST); 6789 6790 format %{ "STFD $src, $mem" %} 6791 size(4); 6792 ins_encode( enc_stfd(src, mem) ); 6793 ins_pipe(pipe_class_memory); 6794 %} 6795 6796 //----------Store Instructions With Zeros-------------------------------------- 6797 6798 // Card-mark for CMS garbage collection. 6799 // This cardmark does an optimization so that it must not always 6800 // do a releasing store. For this, it gets the address of 6801 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6802 // (Using releaseFieldAddr in the match rule is a hack.) 6803 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6804 match(Set mem (StoreCM mem releaseFieldAddr)); 6805 effect(TEMP crx); 6806 predicate(false); 6807 ins_cost(MEMORY_REF_COST); 6808 6809 // See loadConP. 6810 ins_cannot_rematerialize(true); 6811 6812 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6813 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6814 ins_pipe(pipe_class_memory); 6815 %} 6816 6817 // Card-mark for CMS garbage collection. 6818 // This cardmark does an optimization so that it must not always 6819 // do a releasing store. For this, it needs the constant address of 6820 // CMSCollectorCardTableModRefBSExt::_requires_release. 6821 // This constant address is split off here by expand so we can use 6822 // adlc / matcher functionality to load it from the constant section. 6823 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6824 match(Set mem (StoreCM mem zero)); 6825 predicate(UseConcMarkSweepGC); 6826 6827 expand %{ 6828 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6829 iRegLdst releaseFieldAddress; 6830 flagsReg crx; 6831 loadConL_Ex(releaseFieldAddress, baseImm); 6832 storeCM_CMS(mem, releaseFieldAddress, crx); 6833 %} 6834 %} 6835 6836 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6837 match(Set mem (StoreCM mem zero)); 6838 predicate(UseG1GC); 6839 ins_cost(MEMORY_REF_COST); 6840 6841 ins_cannot_rematerialize(true); 6842 6843 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6844 size(8); 6845 ins_encode %{ 6846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6847 __ li(R0, 0); 6848 //__ release(); // G1: oops are allowed to get visible after dirty marking 6849 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6850 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6851 %} 6852 ins_pipe(pipe_class_memory); 6853 %} 6854 6855 // Convert oop pointer into compressed form. 6856 6857 // Nodes for postalloc expand. 6858 6859 // Shift node for expand. 6860 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6861 // The match rule is needed to make it a 'MachTypeNode'! 6862 match(Set dst (EncodeP src)); 6863 predicate(false); 6864 6865 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6866 size(4); 6867 ins_encode %{ 6868 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6869 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6870 %} 6871 ins_pipe(pipe_class_default); 6872 %} 6873 6874 // Add node for expand. 6875 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6876 // The match rule is needed to make it a 'MachTypeNode'! 6877 match(Set dst (EncodeP src)); 6878 predicate(false); 6879 6880 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6881 ins_encode %{ 6882 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6883 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6884 %} 6885 ins_pipe(pipe_class_default); 6886 %} 6887 6888 // Conditional sub base. 6889 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6890 // The match rule is needed to make it a 'MachTypeNode'! 6891 match(Set dst (EncodeP (Binary crx src1))); 6892 predicate(false); 6893 6894 format %{ "BEQ $crx, done\n\t" 6895 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6896 "done:" %} 6897 ins_encode %{ 6898 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6899 Label done; 6900 __ beq($crx$$CondRegister, done); 6901 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6902 __ bind(done); 6903 %} 6904 ins_pipe(pipe_class_default); 6905 %} 6906 6907 // Power 7 can use isel instruction 6908 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6909 // The match rule is needed to make it a 'MachTypeNode'! 6910 match(Set dst (EncodeP (Binary crx src1))); 6911 predicate(false); 6912 6913 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6914 size(4); 6915 ins_encode %{ 6916 // This is a Power7 instruction for which no machine description exists. 6917 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6918 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6919 %} 6920 ins_pipe(pipe_class_default); 6921 %} 6922 6923 // Disjoint narrow oop base. 6924 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6925 match(Set dst (EncodeP src)); 6926 predicate(Universe::narrow_oop_base_disjoint()); 6927 6928 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6929 size(4); 6930 ins_encode %{ 6931 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6932 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6933 %} 6934 ins_pipe(pipe_class_default); 6935 %} 6936 6937 // shift != 0, base != 0 6938 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6939 match(Set dst (EncodeP src)); 6940 effect(TEMP crx); 6941 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6942 Universe::narrow_oop_shift() != 0 && 6943 Universe::narrow_oop_base_overlaps()); 6944 6945 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6946 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6947 %} 6948 6949 // shift != 0, base != 0 6950 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6951 match(Set dst (EncodeP src)); 6952 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6953 Universe::narrow_oop_shift() != 0 && 6954 Universe::narrow_oop_base_overlaps()); 6955 6956 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6957 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6958 %} 6959 6960 // shift != 0, base == 0 6961 // TODO: This is the same as encodeP_shift. Merge! 6962 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6963 match(Set dst (EncodeP src)); 6964 predicate(Universe::narrow_oop_shift() != 0 && 6965 Universe::narrow_oop_base() ==0); 6966 6967 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6968 size(4); 6969 ins_encode %{ 6970 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6971 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6972 %} 6973 ins_pipe(pipe_class_default); 6974 %} 6975 6976 // Compressed OOPs with narrow_oop_shift == 0. 6977 // shift == 0, base == 0 6978 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6979 match(Set dst (EncodeP src)); 6980 predicate(Universe::narrow_oop_shift() == 0); 6981 6982 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6983 // variable size, 0 or 4. 6984 ins_encode %{ 6985 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6986 __ mr_if_needed($dst$$Register, $src$$Register); 6987 %} 6988 ins_pipe(pipe_class_default); 6989 %} 6990 6991 // Decode nodes. 6992 6993 // Shift node for expand. 6994 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6995 // The match rule is needed to make it a 'MachTypeNode'! 6996 match(Set dst (DecodeN src)); 6997 predicate(false); 6998 6999 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7000 size(4); 7001 ins_encode %{ 7002 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7003 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7004 %} 7005 ins_pipe(pipe_class_default); 7006 %} 7007 7008 // Add node for expand. 7009 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7010 // The match rule is needed to make it a 'MachTypeNode'! 7011 match(Set dst (DecodeN src)); 7012 predicate(false); 7013 7014 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7015 ins_encode %{ 7016 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7017 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7018 %} 7019 ins_pipe(pipe_class_default); 7020 %} 7021 7022 // conditianal add base for expand 7023 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7024 // The match rule is needed to make it a 'MachTypeNode'! 7025 // NOTICE that the rule is nonsense - we just have to make sure that: 7026 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7027 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7028 match(Set dst (DecodeN (Binary crx src))); 7029 predicate(false); 7030 7031 format %{ "BEQ $crx, done\n\t" 7032 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7033 "done:" %} 7034 ins_encode %{ 7035 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7036 Label done; 7037 __ beq($crx$$CondRegister, done); 7038 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7039 __ bind(done); 7040 %} 7041 ins_pipe(pipe_class_default); 7042 %} 7043 7044 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7045 // The match rule is needed to make it a 'MachTypeNode'! 7046 // NOTICE that the rule is nonsense - we just have to make sure that: 7047 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7048 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7049 match(Set dst (DecodeN (Binary crx src1))); 7050 predicate(false); 7051 7052 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7053 size(4); 7054 ins_encode %{ 7055 // This is a Power7 instruction for which no machine description exists. 7056 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7057 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7058 %} 7059 ins_pipe(pipe_class_default); 7060 %} 7061 7062 // shift != 0, base != 0 7063 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7064 match(Set dst (DecodeN src)); 7065 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7066 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7067 Universe::narrow_oop_shift() != 0 && 7068 Universe::narrow_oop_base() != 0); 7069 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7070 effect(TEMP crx); 7071 7072 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7073 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7074 %} 7075 7076 // shift != 0, base == 0 7077 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7078 match(Set dst (DecodeN src)); 7079 predicate(Universe::narrow_oop_shift() != 0 && 7080 Universe::narrow_oop_base() == 0); 7081 7082 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7083 size(4); 7084 ins_encode %{ 7085 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7086 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7087 %} 7088 ins_pipe(pipe_class_default); 7089 %} 7090 7091 // Optimize DecodeN for disjoint base. 7092 // Shift narrow oop and or it into register that already contains the heap base. 7093 // Base == dst must hold, and is assured by construction in postaloc_expand. 7094 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7095 match(Set dst (DecodeN src)); 7096 effect(TEMP base); 7097 predicate(false); 7098 7099 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7100 size(4); 7101 ins_encode %{ 7102 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7103 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7104 %} 7105 ins_pipe(pipe_class_default); 7106 %} 7107 7108 // Optimize DecodeN for disjoint base. 7109 // This node requires only one cycle on the critical path. 7110 // We must postalloc_expand as we can not express use_def effects where 7111 // the used register is L and the def'ed register P. 7112 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7113 match(Set dst (DecodeN src)); 7114 effect(TEMP_DEF dst); 7115 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7116 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7117 Universe::narrow_oop_base_disjoint()); 7118 ins_cost(DEFAULT_COST); 7119 7120 format %{ "MOV $dst, heapbase \t\n" 7121 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7122 postalloc_expand %{ 7123 loadBaseNode *n1 = new loadBaseNode(); 7124 n1->add_req(NULL); 7125 n1->_opnds[0] = op_dst; 7126 7127 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7128 n2->add_req(n_region, n_src, n1); 7129 n2->_opnds[0] = op_dst; 7130 n2->_opnds[1] = op_src; 7131 n2->_opnds[2] = op_dst; 7132 n2->_bottom_type = _bottom_type; 7133 7134 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7135 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7136 7137 nodes->push(n1); 7138 nodes->push(n2); 7139 %} 7140 %} 7141 7142 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7143 match(Set dst (DecodeN src)); 7144 effect(TEMP_DEF dst, TEMP crx); 7145 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7146 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7147 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7148 ins_cost(3 * DEFAULT_COST); 7149 7150 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7151 postalloc_expand %{ 7152 loadBaseNode *n1 = new loadBaseNode(); 7153 n1->add_req(NULL); 7154 n1->_opnds[0] = op_dst; 7155 7156 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7157 n_compare->add_req(n_region, n_src); 7158 n_compare->_opnds[0] = op_crx; 7159 n_compare->_opnds[1] = op_src; 7160 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7161 7162 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7163 n2->add_req(n_region, n_src, n1); 7164 n2->_opnds[0] = op_dst; 7165 n2->_opnds[1] = op_src; 7166 n2->_opnds[2] = op_dst; 7167 n2->_bottom_type = _bottom_type; 7168 7169 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7170 n_cond_set->add_req(n_region, n_compare, n2); 7171 n_cond_set->_opnds[0] = op_dst; 7172 n_cond_set->_opnds[1] = op_crx; 7173 n_cond_set->_opnds[2] = op_dst; 7174 n_cond_set->_bottom_type = _bottom_type; 7175 7176 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7177 ra_->set_oop(n_cond_set, true); 7178 7179 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7180 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7181 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7182 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7183 7184 nodes->push(n1); 7185 nodes->push(n_compare); 7186 nodes->push(n2); 7187 nodes->push(n_cond_set); 7188 %} 7189 %} 7190 7191 // src != 0, shift != 0, base != 0 7192 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7193 match(Set dst (DecodeN src)); 7194 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7195 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7196 Universe::narrow_oop_shift() != 0 && 7197 Universe::narrow_oop_base() != 0); 7198 ins_cost(2 * DEFAULT_COST); 7199 7200 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7201 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7202 %} 7203 7204 // Compressed OOPs with narrow_oop_shift == 0. 7205 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7206 match(Set dst (DecodeN src)); 7207 predicate(Universe::narrow_oop_shift() == 0); 7208 ins_cost(DEFAULT_COST); 7209 7210 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7211 // variable size, 0 or 4. 7212 ins_encode %{ 7213 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7214 __ mr_if_needed($dst$$Register, $src$$Register); 7215 %} 7216 ins_pipe(pipe_class_default); 7217 %} 7218 7219 // Convert compressed oop into int for vectors alignment masking. 7220 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7221 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7222 predicate(Universe::narrow_oop_shift() == 0); 7223 ins_cost(DEFAULT_COST); 7224 7225 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7226 // variable size, 0 or 4. 7227 ins_encode %{ 7228 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7229 __ mr_if_needed($dst$$Register, $src$$Register); 7230 %} 7231 ins_pipe(pipe_class_default); 7232 %} 7233 7234 // Convert klass pointer into compressed form. 7235 7236 // Nodes for postalloc expand. 7237 7238 // Shift node for expand. 7239 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7240 // The match rule is needed to make it a 'MachTypeNode'! 7241 match(Set dst (EncodePKlass src)); 7242 predicate(false); 7243 7244 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7245 size(4); 7246 ins_encode %{ 7247 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7248 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7249 %} 7250 ins_pipe(pipe_class_default); 7251 %} 7252 7253 // Add node for expand. 7254 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7255 // The match rule is needed to make it a 'MachTypeNode'! 7256 match(Set dst (EncodePKlass (Binary base src))); 7257 predicate(false); 7258 7259 format %{ "SUB $dst, $base, $src \t// encode" %} 7260 size(4); 7261 ins_encode %{ 7262 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7263 __ subf($dst$$Register, $base$$Register, $src$$Register); 7264 %} 7265 ins_pipe(pipe_class_default); 7266 %} 7267 7268 // Disjoint narrow oop base. 7269 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7270 match(Set dst (EncodePKlass src)); 7271 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7272 7273 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7274 size(4); 7275 ins_encode %{ 7276 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7277 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7278 %} 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // shift != 0, base != 0 7283 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7284 match(Set dst (EncodePKlass (Binary base src))); 7285 predicate(false); 7286 7287 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7288 postalloc_expand %{ 7289 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7290 n1->add_req(n_region, n_base, n_src); 7291 n1->_opnds[0] = op_dst; 7292 n1->_opnds[1] = op_base; 7293 n1->_opnds[2] = op_src; 7294 n1->_bottom_type = _bottom_type; 7295 7296 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7297 n2->add_req(n_region, n1); 7298 n2->_opnds[0] = op_dst; 7299 n2->_opnds[1] = op_dst; 7300 n2->_bottom_type = _bottom_type; 7301 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7302 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7303 7304 nodes->push(n1); 7305 nodes->push(n2); 7306 %} 7307 %} 7308 7309 // shift != 0, base != 0 7310 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7311 match(Set dst (EncodePKlass src)); 7312 //predicate(Universe::narrow_klass_shift() != 0 && 7313 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7314 7315 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7316 ins_cost(DEFAULT_COST*2); // Don't count constant. 7317 expand %{ 7318 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7319 iRegLdst base; 7320 loadConL_Ex(base, baseImm); 7321 encodePKlass_not_null_Ex(dst, base, src); 7322 %} 7323 %} 7324 7325 // Decode nodes. 7326 7327 // Shift node for expand. 7328 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7329 // The match rule is needed to make it a 'MachTypeNode'! 7330 match(Set dst (DecodeNKlass src)); 7331 predicate(false); 7332 7333 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7334 size(4); 7335 ins_encode %{ 7336 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7337 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7338 %} 7339 ins_pipe(pipe_class_default); 7340 %} 7341 7342 // Add node for expand. 7343 7344 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7345 // The match rule is needed to make it a 'MachTypeNode'! 7346 match(Set dst (DecodeNKlass (Binary base src))); 7347 predicate(false); 7348 7349 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7350 size(4); 7351 ins_encode %{ 7352 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7353 __ add($dst$$Register, $base$$Register, $src$$Register); 7354 %} 7355 ins_pipe(pipe_class_default); 7356 %} 7357 7358 // src != 0, shift != 0, base != 0 7359 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7360 match(Set dst (DecodeNKlass (Binary base src))); 7361 //effect(kill src); // We need a register for the immediate result after shifting. 7362 predicate(false); 7363 7364 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7365 postalloc_expand %{ 7366 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7367 n1->add_req(n_region, n_base, n_src); 7368 n1->_opnds[0] = op_dst; 7369 n1->_opnds[1] = op_base; 7370 n1->_opnds[2] = op_src; 7371 n1->_bottom_type = _bottom_type; 7372 7373 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7374 n2->add_req(n_region, n1); 7375 n2->_opnds[0] = op_dst; 7376 n2->_opnds[1] = op_dst; 7377 n2->_bottom_type = _bottom_type; 7378 7379 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7380 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7381 7382 nodes->push(n1); 7383 nodes->push(n2); 7384 %} 7385 %} 7386 7387 // src != 0, shift != 0, base != 0 7388 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7389 match(Set dst (DecodeNKlass src)); 7390 // predicate(Universe::narrow_klass_shift() != 0 && 7391 // Universe::narrow_klass_base() != 0); 7392 7393 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7394 7395 ins_cost(DEFAULT_COST*2); // Don't count constant. 7396 expand %{ 7397 // We add first, then we shift. Like this, we can get along with one register less. 7398 // But we have to load the base pre-shifted. 7399 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7400 iRegLdst base; 7401 loadConL_Ex(base, baseImm); 7402 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7403 %} 7404 %} 7405 7406 //----------MemBar Instructions----------------------------------------------- 7407 // Memory barrier flavors 7408 7409 instruct membar_acquire() %{ 7410 match(LoadFence); 7411 ins_cost(4*MEMORY_REF_COST); 7412 7413 format %{ "MEMBAR-acquire" %} 7414 size(4); 7415 ins_encode %{ 7416 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7417 __ acquire(); 7418 %} 7419 ins_pipe(pipe_class_default); 7420 %} 7421 7422 instruct unnecessary_membar_acquire() %{ 7423 match(MemBarAcquire); 7424 ins_cost(0); 7425 7426 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7427 size(0); 7428 ins_encode( /*empty*/ ); 7429 ins_pipe(pipe_class_default); 7430 %} 7431 7432 instruct membar_acquire_lock() %{ 7433 match(MemBarAcquireLock); 7434 ins_cost(0); 7435 7436 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7437 size(0); 7438 ins_encode( /*empty*/ ); 7439 ins_pipe(pipe_class_default); 7440 %} 7441 7442 instruct membar_release() %{ 7443 match(MemBarRelease); 7444 match(StoreFence); 7445 ins_cost(4*MEMORY_REF_COST); 7446 7447 format %{ "MEMBAR-release" %} 7448 size(4); 7449 ins_encode %{ 7450 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7451 __ release(); 7452 %} 7453 ins_pipe(pipe_class_default); 7454 %} 7455 7456 instruct membar_storestore() %{ 7457 match(MemBarStoreStore); 7458 ins_cost(4*MEMORY_REF_COST); 7459 7460 format %{ "MEMBAR-store-store" %} 7461 size(4); 7462 ins_encode %{ 7463 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7464 __ membar(Assembler::StoreStore); 7465 %} 7466 ins_pipe(pipe_class_default); 7467 %} 7468 7469 instruct membar_release_lock() %{ 7470 match(MemBarReleaseLock); 7471 ins_cost(0); 7472 7473 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7474 size(0); 7475 ins_encode( /*empty*/ ); 7476 ins_pipe(pipe_class_default); 7477 %} 7478 7479 instruct membar_volatile() %{ 7480 match(MemBarVolatile); 7481 ins_cost(4*MEMORY_REF_COST); 7482 7483 format %{ "MEMBAR-volatile" %} 7484 size(4); 7485 ins_encode %{ 7486 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7487 __ fence(); 7488 %} 7489 ins_pipe(pipe_class_default); 7490 %} 7491 7492 // This optimization is wrong on PPC. The following pattern is not supported: 7493 // MemBarVolatile 7494 // ^ ^ 7495 // | | 7496 // CtrlProj MemProj 7497 // ^ ^ 7498 // | | 7499 // | Load 7500 // | 7501 // MemBarVolatile 7502 // 7503 // The first MemBarVolatile could get optimized out! According to 7504 // Vladimir, this pattern can not occur on Oracle platforms. 7505 // However, it does occur on PPC64 (because of membars in 7506 // inline_unsafe_load_store). 7507 // 7508 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7509 // Don't forget to look at the implementation of post_store_load_barrier again, 7510 // we did other fixes in that method. 7511 //instruct unnecessary_membar_volatile() %{ 7512 // match(MemBarVolatile); 7513 // predicate(Matcher::post_store_load_barrier(n)); 7514 // ins_cost(0); 7515 // 7516 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7517 // size(0); 7518 // ins_encode( /*empty*/ ); 7519 // ins_pipe(pipe_class_default); 7520 //%} 7521 7522 instruct membar_CPUOrder() %{ 7523 match(MemBarCPUOrder); 7524 ins_cost(0); 7525 7526 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7527 size(0); 7528 ins_encode( /*empty*/ ); 7529 ins_pipe(pipe_class_default); 7530 %} 7531 7532 //----------Conditional Move--------------------------------------------------- 7533 7534 // Cmove using isel. 7535 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7536 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7537 predicate(VM_Version::has_isel()); 7538 ins_cost(DEFAULT_COST); 7539 7540 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7541 size(4); 7542 ins_encode %{ 7543 // This is a Power7 instruction for which no machine description 7544 // exists. Anyways, the scheduler should be off on Power7. 7545 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7546 int cc = $cmp$$cmpcode; 7547 __ isel($dst$$Register, $crx$$CondRegister, 7548 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7549 %} 7550 ins_pipe(pipe_class_default); 7551 %} 7552 7553 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7554 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7555 predicate(!VM_Version::has_isel()); 7556 ins_cost(DEFAULT_COST+BRANCH_COST); 7557 7558 ins_variable_size_depending_on_alignment(true); 7559 7560 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7561 // Worst case is branch + move + stop, no stop without scheduler 7562 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7563 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7564 ins_pipe(pipe_class_default); 7565 %} 7566 7567 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7568 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7569 ins_cost(DEFAULT_COST+BRANCH_COST); 7570 7571 ins_variable_size_depending_on_alignment(true); 7572 7573 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7574 // Worst case is branch + move + stop, no stop without scheduler 7575 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7576 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7577 ins_pipe(pipe_class_default); 7578 %} 7579 7580 // Cmove using isel. 7581 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7582 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7583 predicate(VM_Version::has_isel()); 7584 ins_cost(DEFAULT_COST); 7585 7586 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7587 size(4); 7588 ins_encode %{ 7589 // This is a Power7 instruction for which no machine description 7590 // exists. Anyways, the scheduler should be off on Power7. 7591 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7592 int cc = $cmp$$cmpcode; 7593 __ isel($dst$$Register, $crx$$CondRegister, 7594 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7595 %} 7596 ins_pipe(pipe_class_default); 7597 %} 7598 7599 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7600 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7601 predicate(!VM_Version::has_isel()); 7602 ins_cost(DEFAULT_COST+BRANCH_COST); 7603 7604 ins_variable_size_depending_on_alignment(true); 7605 7606 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7607 // Worst case is branch + move + stop, no stop without scheduler. 7608 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7609 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7610 ins_pipe(pipe_class_default); 7611 %} 7612 7613 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7614 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7615 ins_cost(DEFAULT_COST+BRANCH_COST); 7616 7617 ins_variable_size_depending_on_alignment(true); 7618 7619 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7620 // Worst case is branch + move + stop, no stop without scheduler. 7621 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7622 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7623 ins_pipe(pipe_class_default); 7624 %} 7625 7626 // Cmove using isel. 7627 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7628 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7629 predicate(VM_Version::has_isel()); 7630 ins_cost(DEFAULT_COST); 7631 7632 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7633 size(4); 7634 ins_encode %{ 7635 // This is a Power7 instruction for which no machine description 7636 // exists. Anyways, the scheduler should be off on Power7. 7637 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7638 int cc = $cmp$$cmpcode; 7639 __ isel($dst$$Register, $crx$$CondRegister, 7640 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7641 %} 7642 ins_pipe(pipe_class_default); 7643 %} 7644 7645 // Conditional move for RegN. Only cmov(reg, reg). 7646 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7647 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7648 predicate(!VM_Version::has_isel()); 7649 ins_cost(DEFAULT_COST+BRANCH_COST); 7650 7651 ins_variable_size_depending_on_alignment(true); 7652 7653 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7654 // Worst case is branch + move + stop, no stop without scheduler. 7655 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7656 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7657 ins_pipe(pipe_class_default); 7658 %} 7659 7660 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7661 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7662 ins_cost(DEFAULT_COST+BRANCH_COST); 7663 7664 ins_variable_size_depending_on_alignment(true); 7665 7666 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7667 // Worst case is branch + move + stop, no stop without scheduler. 7668 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7669 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7670 ins_pipe(pipe_class_default); 7671 %} 7672 7673 // Cmove using isel. 7674 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7675 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7676 predicate(VM_Version::has_isel()); 7677 ins_cost(DEFAULT_COST); 7678 7679 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7680 size(4); 7681 ins_encode %{ 7682 // This is a Power7 instruction for which no machine description 7683 // exists. Anyways, the scheduler should be off on Power7. 7684 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7685 int cc = $cmp$$cmpcode; 7686 __ isel($dst$$Register, $crx$$CondRegister, 7687 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7688 %} 7689 ins_pipe(pipe_class_default); 7690 %} 7691 7692 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7693 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7694 predicate(!VM_Version::has_isel()); 7695 ins_cost(DEFAULT_COST+BRANCH_COST); 7696 7697 ins_variable_size_depending_on_alignment(true); 7698 7699 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7700 // Worst case is branch + move + stop, no stop without scheduler. 7701 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7702 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7703 ins_pipe(pipe_class_default); 7704 %} 7705 7706 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7707 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7708 ins_cost(DEFAULT_COST+BRANCH_COST); 7709 7710 ins_variable_size_depending_on_alignment(true); 7711 7712 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7713 // Worst case is branch + move + stop, no stop without scheduler. 7714 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7715 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7716 ins_pipe(pipe_class_default); 7717 %} 7718 7719 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7720 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7721 ins_cost(DEFAULT_COST+BRANCH_COST); 7722 7723 ins_variable_size_depending_on_alignment(true); 7724 7725 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7726 // Worst case is branch + move + stop, no stop without scheduler. 7727 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7728 ins_encode %{ 7729 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7730 Label done; 7731 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7732 // Branch if not (cmp crx). 7733 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7734 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7735 // TODO PPC port __ endgroup_if_needed(_size == 12); 7736 __ bind(done); 7737 %} 7738 ins_pipe(pipe_class_default); 7739 %} 7740 7741 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7742 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7743 ins_cost(DEFAULT_COST+BRANCH_COST); 7744 7745 ins_variable_size_depending_on_alignment(true); 7746 7747 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7748 // Worst case is branch + move + stop, no stop without scheduler. 7749 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7750 ins_encode %{ 7751 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7752 Label done; 7753 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7754 // Branch if not (cmp crx). 7755 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7756 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7757 // TODO PPC port __ endgroup_if_needed(_size == 12); 7758 __ bind(done); 7759 %} 7760 ins_pipe(pipe_class_default); 7761 %} 7762 7763 //----------Conditional_store-------------------------------------------------- 7764 // Conditional-store of the updated heap-top. 7765 // Used during allocation of the shared heap. 7766 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7767 7768 // As compareAndSwapL, but return flag register instead of boolean value in 7769 // int register. 7770 // Used by sun/misc/AtomicLongCSImpl.java. 7771 // Mem_ptr must be a memory operand, else this node does not get 7772 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7773 // can be rematerialized which leads to errors. 7774 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7775 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7776 effect(TEMP cr0); 7777 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7778 ins_encode %{ 7779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7780 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7781 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7782 noreg, NULL, true); 7783 %} 7784 ins_pipe(pipe_class_default); 7785 %} 7786 7787 // As compareAndSwapP, but return flag register instead of boolean value in 7788 // int register. 7789 // This instruction is matched if UseTLAB is off. 7790 // Mem_ptr must be a memory operand, else this node does not get 7791 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7792 // can be rematerialized which leads to errors. 7793 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7794 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7795 ins_cost(2*MEMORY_REF_COST); 7796 7797 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7798 ins_encode %{ 7799 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7800 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7801 %} 7802 ins_pipe(pipe_class_memory); 7803 %} 7804 7805 // Implement LoadPLocked. Must be ordered against changes of the memory location 7806 // by storePConditional. 7807 // Don't know whether this is ever used. 7808 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7809 match(Set dst (LoadPLocked mem)); 7810 ins_cost(2*MEMORY_REF_COST); 7811 7812 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7813 size(4); 7814 ins_encode %{ 7815 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7816 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7817 %} 7818 ins_pipe(pipe_class_memory); 7819 %} 7820 7821 //----------Compare-And-Swap--------------------------------------------------- 7822 7823 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7824 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7825 // matched. 7826 7827 // Strong versions: 7828 7829 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7830 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7831 predicate(VM_Version::has_lqarx()); 7832 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7833 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7834 ins_encode %{ 7835 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7836 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7837 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7838 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7839 $res$$Register, true); 7840 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7841 __ isync(); 7842 } else { 7843 __ sync(); 7844 } 7845 %} 7846 ins_pipe(pipe_class_default); 7847 %} 7848 7849 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7850 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7851 predicate(!VM_Version::has_lqarx()); 7852 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7853 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7854 ins_encode %{ 7855 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7856 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7857 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7858 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7859 $res$$Register, true); 7860 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7861 __ isync(); 7862 } else { 7863 __ sync(); 7864 } 7865 %} 7866 ins_pipe(pipe_class_default); 7867 %} 7868 7869 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7870 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7871 predicate(VM_Version::has_lqarx()); 7872 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7873 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7874 ins_encode %{ 7875 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7876 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7877 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7878 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7879 $res$$Register, true); 7880 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7881 __ isync(); 7882 } else { 7883 __ sync(); 7884 } 7885 %} 7886 ins_pipe(pipe_class_default); 7887 %} 7888 7889 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7890 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7891 predicate(!VM_Version::has_lqarx()); 7892 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7893 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7894 ins_encode %{ 7895 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7896 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7897 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7898 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7899 $res$$Register, true); 7900 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7901 __ isync(); 7902 } else { 7903 __ sync(); 7904 } 7905 %} 7906 ins_pipe(pipe_class_default); 7907 %} 7908 7909 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7910 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7911 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7912 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7913 ins_encode %{ 7914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7915 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7916 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7917 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7918 $res$$Register, true); 7919 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7920 __ isync(); 7921 } else { 7922 __ sync(); 7923 } 7924 %} 7925 ins_pipe(pipe_class_default); 7926 %} 7927 7928 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7929 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7930 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7931 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7932 ins_encode %{ 7933 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7934 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7935 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7936 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7937 $res$$Register, true); 7938 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7939 __ isync(); 7940 } else { 7941 __ sync(); 7942 } 7943 %} 7944 ins_pipe(pipe_class_default); 7945 %} 7946 7947 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7948 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7949 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7950 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7951 ins_encode %{ 7952 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7953 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7954 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7955 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7956 $res$$Register, NULL, true); 7957 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7958 __ isync(); 7959 } else { 7960 __ sync(); 7961 } 7962 %} 7963 ins_pipe(pipe_class_default); 7964 %} 7965 7966 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7967 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7968 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7969 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7970 ins_encode %{ 7971 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7972 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7973 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7974 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7975 $res$$Register, NULL, true); 7976 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7977 __ isync(); 7978 } else { 7979 __ sync(); 7980 } 7981 %} 7982 ins_pipe(pipe_class_default); 7983 %} 7984 7985 // Weak versions: 7986 7987 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7988 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7989 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7990 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7991 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7992 ins_encode %{ 7993 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7994 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7995 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7996 MacroAssembler::MemBarNone, 7997 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7998 %} 7999 ins_pipe(pipe_class_default); 8000 %} 8001 8002 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8003 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8004 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8005 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8006 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8007 ins_encode %{ 8008 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8009 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8010 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8011 MacroAssembler::MemBarNone, 8012 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8013 %} 8014 ins_pipe(pipe_class_default); 8015 %} 8016 8017 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8018 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8019 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8020 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8021 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8022 ins_encode %{ 8023 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8024 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8025 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8026 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8027 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8028 %} 8029 ins_pipe(pipe_class_default); 8030 %} 8031 8032 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8033 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8034 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8035 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8036 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8037 ins_encode %{ 8038 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8039 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8040 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8041 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8042 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8043 %} 8044 ins_pipe(pipe_class_default); 8045 %} 8046 8047 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8048 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8049 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8050 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8051 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8052 ins_encode %{ 8053 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8054 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8055 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8056 MacroAssembler::MemBarNone, 8057 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8058 %} 8059 ins_pipe(pipe_class_default); 8060 %} 8061 8062 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8063 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8064 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8065 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8066 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8067 ins_encode %{ 8068 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8069 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8070 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8071 MacroAssembler::MemBarNone, 8072 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8073 %} 8074 ins_pipe(pipe_class_default); 8075 %} 8076 8077 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8078 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8079 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8080 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8081 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8082 ins_encode %{ 8083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8084 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8085 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8086 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8087 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8088 %} 8089 ins_pipe(pipe_class_default); 8090 %} 8091 8092 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8093 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8094 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8095 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8096 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8097 ins_encode %{ 8098 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8099 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8100 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8101 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8102 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8103 %} 8104 ins_pipe(pipe_class_default); 8105 %} 8106 8107 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8108 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8109 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8110 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8111 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8112 ins_encode %{ 8113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8115 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8116 MacroAssembler::MemBarNone, 8117 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8118 %} 8119 ins_pipe(pipe_class_default); 8120 %} 8121 8122 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8123 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8124 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8125 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8126 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8127 ins_encode %{ 8128 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8129 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8130 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8131 // value is never passed to caller. 8132 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8133 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8134 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8135 %} 8136 ins_pipe(pipe_class_default); 8137 %} 8138 8139 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8140 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8141 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8142 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8143 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8144 ins_encode %{ 8145 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8146 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8147 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8148 MacroAssembler::MemBarNone, 8149 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8150 %} 8151 ins_pipe(pipe_class_default); 8152 %} 8153 8154 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8155 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8156 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8157 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8158 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8159 ins_encode %{ 8160 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8161 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8162 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8163 // value is never passed to caller. 8164 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8165 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8166 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8167 %} 8168 ins_pipe(pipe_class_default); 8169 %} 8170 8171 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8172 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8173 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8174 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8175 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8176 ins_encode %{ 8177 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8178 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8179 // value is never passed to caller. 8180 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8181 MacroAssembler::MemBarNone, 8182 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8183 %} 8184 ins_pipe(pipe_class_default); 8185 %} 8186 8187 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8188 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8189 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8190 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8191 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8192 ins_encode %{ 8193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8194 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8195 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8196 // value is never passed to caller. 8197 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8198 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8199 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8200 %} 8201 ins_pipe(pipe_class_default); 8202 %} 8203 8204 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8205 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8206 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8207 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8208 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8209 ins_encode %{ 8210 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8211 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8212 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8213 MacroAssembler::MemBarNone, 8214 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8215 %} 8216 ins_pipe(pipe_class_default); 8217 %} 8218 8219 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8220 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8221 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8222 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8223 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8224 ins_encode %{ 8225 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8226 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8227 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8228 // value is never passed to caller. 8229 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8230 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8231 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8232 %} 8233 ins_pipe(pipe_class_default); 8234 %} 8235 8236 // CompareAndExchange 8237 8238 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8239 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8240 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8241 effect(TEMP_DEF res, TEMP cr0); 8242 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8243 ins_encode %{ 8244 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8245 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8246 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8247 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8248 noreg, true); 8249 %} 8250 ins_pipe(pipe_class_default); 8251 %} 8252 8253 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8254 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8255 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8256 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8257 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8258 ins_encode %{ 8259 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8260 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8261 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8262 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8263 noreg, true); 8264 %} 8265 ins_pipe(pipe_class_default); 8266 %} 8267 8268 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8269 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8270 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8271 effect(TEMP_DEF res, TEMP cr0); 8272 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8273 ins_encode %{ 8274 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8275 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8276 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8277 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8278 noreg, true); 8279 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8280 __ isync(); 8281 } else { 8282 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8283 __ sync(); 8284 } 8285 %} 8286 ins_pipe(pipe_class_default); 8287 %} 8288 8289 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8290 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8291 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8292 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8293 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8294 ins_encode %{ 8295 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8296 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8297 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8298 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8299 noreg, true); 8300 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8301 __ isync(); 8302 } else { 8303 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8304 __ sync(); 8305 } 8306 %} 8307 ins_pipe(pipe_class_default); 8308 %} 8309 8310 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8311 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8312 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8313 effect(TEMP_DEF res, TEMP cr0); 8314 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8315 ins_encode %{ 8316 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8317 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8318 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8319 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8320 noreg, true); 8321 %} 8322 ins_pipe(pipe_class_default); 8323 %} 8324 8325 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8326 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8327 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8328 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8329 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8330 ins_encode %{ 8331 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8332 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8333 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8334 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8335 noreg, true); 8336 %} 8337 ins_pipe(pipe_class_default); 8338 %} 8339 8340 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8341 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8342 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8343 effect(TEMP_DEF res, TEMP cr0); 8344 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8345 ins_encode %{ 8346 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8347 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8348 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8349 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8350 noreg, true); 8351 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8352 __ isync(); 8353 } else { 8354 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8355 __ sync(); 8356 } 8357 %} 8358 ins_pipe(pipe_class_default); 8359 %} 8360 8361 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8362 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8363 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8364 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8365 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8366 ins_encode %{ 8367 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8368 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8369 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8370 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8371 noreg, true); 8372 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8373 __ isync(); 8374 } else { 8375 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8376 __ sync(); 8377 } 8378 %} 8379 ins_pipe(pipe_class_default); 8380 %} 8381 8382 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8383 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8384 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8385 effect(TEMP_DEF res, TEMP cr0); 8386 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8387 ins_encode %{ 8388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8389 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8390 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8391 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8392 noreg, true); 8393 %} 8394 ins_pipe(pipe_class_default); 8395 %} 8396 8397 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8398 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8399 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8400 effect(TEMP_DEF res, TEMP cr0); 8401 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8402 ins_encode %{ 8403 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8404 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8405 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8406 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8407 noreg, true); 8408 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8409 __ isync(); 8410 } else { 8411 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8412 __ sync(); 8413 } 8414 %} 8415 ins_pipe(pipe_class_default); 8416 %} 8417 8418 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8419 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8420 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8421 effect(TEMP_DEF res, TEMP cr0); 8422 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8423 ins_encode %{ 8424 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8425 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8426 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8427 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8428 noreg, true); 8429 %} 8430 ins_pipe(pipe_class_default); 8431 %} 8432 8433 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8434 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8435 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8436 effect(TEMP_DEF res, TEMP cr0); 8437 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8438 ins_encode %{ 8439 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8440 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8441 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8442 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8443 noreg, true); 8444 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8445 __ isync(); 8446 } else { 8447 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8448 __ sync(); 8449 } 8450 %} 8451 ins_pipe(pipe_class_default); 8452 %} 8453 8454 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8455 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8456 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8457 effect(TEMP_DEF res, TEMP cr0); 8458 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8459 ins_encode %{ 8460 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8461 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8462 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8463 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8464 noreg, NULL, true); 8465 %} 8466 ins_pipe(pipe_class_default); 8467 %} 8468 8469 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8470 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8471 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8472 effect(TEMP_DEF res, TEMP cr0); 8473 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8474 ins_encode %{ 8475 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8476 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8477 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8478 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8479 noreg, NULL, true); 8480 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8481 __ isync(); 8482 } else { 8483 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8484 __ sync(); 8485 } 8486 %} 8487 ins_pipe(pipe_class_default); 8488 %} 8489 8490 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8491 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8492 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8493 effect(TEMP_DEF res, TEMP cr0); 8494 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8495 ins_encode %{ 8496 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8497 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8498 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8499 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8500 noreg, NULL, true); 8501 %} 8502 ins_pipe(pipe_class_default); 8503 %} 8504 8505 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8506 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8507 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8508 effect(TEMP_DEF res, TEMP cr0); 8509 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8510 ins_encode %{ 8511 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8512 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8513 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8514 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8515 noreg, NULL, true); 8516 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8517 __ isync(); 8518 } else { 8519 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8520 __ sync(); 8521 } 8522 %} 8523 ins_pipe(pipe_class_default); 8524 %} 8525 8526 // Special RMW 8527 8528 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8529 match(Set res (GetAndAddB mem_ptr src)); 8530 predicate(VM_Version::has_lqarx()); 8531 effect(TEMP_DEF res, TEMP cr0); 8532 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8533 ins_encode %{ 8534 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8535 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8536 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8537 __ isync(); 8538 } else { 8539 __ sync(); 8540 } 8541 %} 8542 ins_pipe(pipe_class_default); 8543 %} 8544 8545 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8546 match(Set res (GetAndAddB mem_ptr src)); 8547 predicate(!VM_Version::has_lqarx()); 8548 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8549 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8550 ins_encode %{ 8551 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8552 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8553 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8554 __ isync(); 8555 } else { 8556 __ sync(); 8557 } 8558 %} 8559 ins_pipe(pipe_class_default); 8560 %} 8561 8562 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8563 match(Set res (GetAndAddS mem_ptr src)); 8564 predicate(VM_Version::has_lqarx()); 8565 effect(TEMP_DEF res, TEMP cr0); 8566 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8567 ins_encode %{ 8568 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8569 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8570 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8571 __ isync(); 8572 } else { 8573 __ sync(); 8574 } 8575 %} 8576 ins_pipe(pipe_class_default); 8577 %} 8578 8579 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8580 match(Set res (GetAndAddS mem_ptr src)); 8581 predicate(!VM_Version::has_lqarx()); 8582 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8583 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8584 ins_encode %{ 8585 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8586 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8587 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8588 __ isync(); 8589 } else { 8590 __ sync(); 8591 } 8592 %} 8593 ins_pipe(pipe_class_default); 8594 %} 8595 8596 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8597 match(Set res (GetAndAddI mem_ptr src)); 8598 effect(TEMP_DEF res, TEMP cr0); 8599 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8600 ins_encode %{ 8601 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8602 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8603 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8604 __ isync(); 8605 } else { 8606 __ sync(); 8607 } 8608 %} 8609 ins_pipe(pipe_class_default); 8610 %} 8611 8612 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8613 match(Set res (GetAndAddL mem_ptr src)); 8614 effect(TEMP_DEF res, TEMP cr0); 8615 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8616 ins_encode %{ 8617 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8618 R0, 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 getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8629 match(Set res (GetAndSetB mem_ptr src)); 8630 predicate(VM_Version::has_lqarx()); 8631 effect(TEMP_DEF res, TEMP cr0); 8632 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8633 ins_encode %{ 8634 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8635 noreg, noreg, noreg, 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 getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8646 match(Set res (GetAndSetB mem_ptr src)); 8647 predicate(!VM_Version::has_lqarx()); 8648 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8649 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8650 ins_encode %{ 8651 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8652 R0, $tmp1$$Register, $tmp2$$Register, 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 getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8663 match(Set res (GetAndSetS mem_ptr src)); 8664 predicate(VM_Version::has_lqarx()); 8665 effect(TEMP_DEF res, TEMP cr0); 8666 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8667 ins_encode %{ 8668 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8669 noreg, noreg, noreg, 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 getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8680 match(Set res (GetAndSetS mem_ptr src)); 8681 predicate(!VM_Version::has_lqarx()); 8682 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8683 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8684 ins_encode %{ 8685 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8686 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8687 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8688 __ isync(); 8689 } else { 8690 __ sync(); 8691 } 8692 %} 8693 ins_pipe(pipe_class_default); 8694 %} 8695 8696 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8697 match(Set res (GetAndSetI mem_ptr src)); 8698 effect(TEMP_DEF res, TEMP cr0); 8699 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8700 ins_encode %{ 8701 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8702 MacroAssembler::cmpxchgx_hint_atomic_update()); 8703 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8704 __ isync(); 8705 } else { 8706 __ sync(); 8707 } 8708 %} 8709 ins_pipe(pipe_class_default); 8710 %} 8711 8712 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8713 match(Set res (GetAndSetL mem_ptr src)); 8714 effect(TEMP_DEF res, TEMP cr0); 8715 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8716 ins_encode %{ 8717 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8718 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 getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8729 match(Set res (GetAndSetP mem_ptr src)); 8730 effect(TEMP_DEF res, TEMP cr0); 8731 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8732 ins_encode %{ 8733 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8734 MacroAssembler::cmpxchgx_hint_atomic_update()); 8735 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8736 __ isync(); 8737 } else { 8738 __ sync(); 8739 } 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8745 match(Set res (GetAndSetN mem_ptr src)); 8746 effect(TEMP_DEF res, TEMP cr0); 8747 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8748 ins_encode %{ 8749 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8750 MacroAssembler::cmpxchgx_hint_atomic_update()); 8751 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8752 __ isync(); 8753 } else { 8754 __ sync(); 8755 } 8756 %} 8757 ins_pipe(pipe_class_default); 8758 %} 8759 8760 //----------Arithmetic Instructions-------------------------------------------- 8761 // Addition Instructions 8762 8763 // Register Addition 8764 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8765 match(Set dst (AddI src1 src2)); 8766 format %{ "ADD $dst, $src1, $src2" %} 8767 size(4); 8768 ins_encode %{ 8769 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8770 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8771 %} 8772 ins_pipe(pipe_class_default); 8773 %} 8774 8775 // Expand does not work with above instruct. (??) 8776 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8777 // no match-rule 8778 effect(DEF dst, USE src1, USE src2); 8779 format %{ "ADD $dst, $src1, $src2" %} 8780 size(4); 8781 ins_encode %{ 8782 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8783 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8784 %} 8785 ins_pipe(pipe_class_default); 8786 %} 8787 8788 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8789 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8790 ins_cost(DEFAULT_COST*3); 8791 8792 expand %{ 8793 // FIXME: we should do this in the ideal world. 8794 iRegIdst tmp1; 8795 iRegIdst tmp2; 8796 addI_reg_reg(tmp1, src1, src2); 8797 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8798 addI_reg_reg(dst, tmp1, tmp2); 8799 %} 8800 %} 8801 8802 // Immediate Addition 8803 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8804 match(Set dst (AddI src1 src2)); 8805 format %{ "ADDI $dst, $src1, $src2" %} 8806 size(4); 8807 ins_encode %{ 8808 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8809 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8810 %} 8811 ins_pipe(pipe_class_default); 8812 %} 8813 8814 // Immediate Addition with 16-bit shifted operand 8815 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8816 match(Set dst (AddI src1 src2)); 8817 format %{ "ADDIS $dst, $src1, $src2" %} 8818 size(4); 8819 ins_encode %{ 8820 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8821 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8822 %} 8823 ins_pipe(pipe_class_default); 8824 %} 8825 8826 // Long Addition 8827 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8828 match(Set dst (AddL src1 src2)); 8829 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8830 size(4); 8831 ins_encode %{ 8832 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8833 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8834 %} 8835 ins_pipe(pipe_class_default); 8836 %} 8837 8838 // Expand does not work with above instruct. (??) 8839 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8840 // no match-rule 8841 effect(DEF dst, USE src1, USE src2); 8842 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8843 size(4); 8844 ins_encode %{ 8845 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8846 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8847 %} 8848 ins_pipe(pipe_class_default); 8849 %} 8850 8851 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8852 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8853 ins_cost(DEFAULT_COST*3); 8854 8855 expand %{ 8856 // FIXME: we should do this in the ideal world. 8857 iRegLdst tmp1; 8858 iRegLdst tmp2; 8859 addL_reg_reg(tmp1, src1, src2); 8860 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8861 addL_reg_reg(dst, tmp1, tmp2); 8862 %} 8863 %} 8864 8865 // AddL + ConvL2I. 8866 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8867 match(Set dst (ConvL2I (AddL src1 src2))); 8868 8869 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8870 size(4); 8871 ins_encode %{ 8872 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8873 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8874 %} 8875 ins_pipe(pipe_class_default); 8876 %} 8877 8878 // No constant pool entries required. 8879 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8880 match(Set dst (AddL src1 src2)); 8881 8882 format %{ "ADDI $dst, $src1, $src2" %} 8883 size(4); 8884 ins_encode %{ 8885 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8886 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8887 %} 8888 ins_pipe(pipe_class_default); 8889 %} 8890 8891 // Long Immediate Addition with 16-bit shifted operand. 8892 // No constant pool entries required. 8893 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8894 match(Set dst (AddL src1 src2)); 8895 8896 format %{ "ADDIS $dst, $src1, $src2" %} 8897 size(4); 8898 ins_encode %{ 8899 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8900 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8901 %} 8902 ins_pipe(pipe_class_default); 8903 %} 8904 8905 // Pointer Register Addition 8906 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8907 match(Set dst (AddP src1 src2)); 8908 format %{ "ADD $dst, $src1, $src2" %} 8909 size(4); 8910 ins_encode %{ 8911 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8912 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8913 %} 8914 ins_pipe(pipe_class_default); 8915 %} 8916 8917 // Pointer Immediate Addition 8918 // No constant pool entries required. 8919 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8920 match(Set dst (AddP src1 src2)); 8921 8922 format %{ "ADDI $dst, $src1, $src2" %} 8923 size(4); 8924 ins_encode %{ 8925 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8926 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8927 %} 8928 ins_pipe(pipe_class_default); 8929 %} 8930 8931 // Pointer Immediate Addition with 16-bit shifted operand. 8932 // No constant pool entries required. 8933 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8934 match(Set dst (AddP src1 src2)); 8935 8936 format %{ "ADDIS $dst, $src1, $src2" %} 8937 size(4); 8938 ins_encode %{ 8939 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8940 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8941 %} 8942 ins_pipe(pipe_class_default); 8943 %} 8944 8945 //--------------------- 8946 // Subtraction Instructions 8947 8948 // Register Subtraction 8949 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8950 match(Set dst (SubI src1 src2)); 8951 format %{ "SUBF $dst, $src2, $src1" %} 8952 size(4); 8953 ins_encode %{ 8954 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8955 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8956 %} 8957 ins_pipe(pipe_class_default); 8958 %} 8959 8960 // Immediate Subtraction 8961 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8962 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8963 8964 // SubI from constant (using subfic). 8965 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8966 match(Set dst (SubI src1 src2)); 8967 format %{ "SUBI $dst, $src1, $src2" %} 8968 8969 size(4); 8970 ins_encode %{ 8971 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8972 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8973 %} 8974 ins_pipe(pipe_class_default); 8975 %} 8976 8977 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8978 // positive integers and 0xF...F for negative ones. 8979 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8980 // no match-rule, false predicate 8981 effect(DEF dst, USE src); 8982 predicate(false); 8983 8984 format %{ "SRAWI $dst, $src, #31" %} 8985 size(4); 8986 ins_encode %{ 8987 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8988 __ srawi($dst$$Register, $src$$Register, 0x1f); 8989 %} 8990 ins_pipe(pipe_class_default); 8991 %} 8992 8993 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8994 match(Set dst (AbsI src)); 8995 ins_cost(DEFAULT_COST*3); 8996 8997 expand %{ 8998 iRegIdst tmp1; 8999 iRegIdst tmp2; 9000 signmask32I_regI(tmp1, src); 9001 xorI_reg_reg(tmp2, tmp1, src); 9002 subI_reg_reg(dst, tmp2, tmp1); 9003 %} 9004 %} 9005 9006 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9007 match(Set dst (SubI zero src2)); 9008 format %{ "NEG $dst, $src2" %} 9009 size(4); 9010 ins_encode %{ 9011 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9012 __ neg($dst$$Register, $src2$$Register); 9013 %} 9014 ins_pipe(pipe_class_default); 9015 %} 9016 9017 // Long subtraction 9018 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9019 match(Set dst (SubL src1 src2)); 9020 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9021 size(4); 9022 ins_encode %{ 9023 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9024 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9025 %} 9026 ins_pipe(pipe_class_default); 9027 %} 9028 9029 // SubL + convL2I. 9030 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9031 match(Set dst (ConvL2I (SubL src1 src2))); 9032 9033 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9034 size(4); 9035 ins_encode %{ 9036 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9037 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9038 %} 9039 ins_pipe(pipe_class_default); 9040 %} 9041 9042 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9043 // positive longs and 0xF...F for negative ones. 9044 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9045 // no match-rule, false predicate 9046 effect(DEF dst, USE src); 9047 predicate(false); 9048 9049 format %{ "SRADI $dst, $src, #63" %} 9050 size(4); 9051 ins_encode %{ 9052 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9053 __ sradi($dst$$Register, $src$$Register, 0x3f); 9054 %} 9055 ins_pipe(pipe_class_default); 9056 %} 9057 9058 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9059 // positive longs and 0xF...F for negative ones. 9060 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9061 // no match-rule, false predicate 9062 effect(DEF dst, USE src); 9063 predicate(false); 9064 9065 format %{ "SRADI $dst, $src, #63" %} 9066 size(4); 9067 ins_encode %{ 9068 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9069 __ sradi($dst$$Register, $src$$Register, 0x3f); 9070 %} 9071 ins_pipe(pipe_class_default); 9072 %} 9073 9074 // Long negation 9075 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9076 match(Set dst (SubL zero src2)); 9077 format %{ "NEG $dst, $src2 \t// long" %} 9078 size(4); 9079 ins_encode %{ 9080 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9081 __ neg($dst$$Register, $src2$$Register); 9082 %} 9083 ins_pipe(pipe_class_default); 9084 %} 9085 9086 // NegL + ConvL2I. 9087 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9088 match(Set dst (ConvL2I (SubL zero src2))); 9089 9090 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9091 size(4); 9092 ins_encode %{ 9093 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9094 __ neg($dst$$Register, $src2$$Register); 9095 %} 9096 ins_pipe(pipe_class_default); 9097 %} 9098 9099 // Multiplication Instructions 9100 // Integer Multiplication 9101 9102 // Register Multiplication 9103 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9104 match(Set dst (MulI src1 src2)); 9105 ins_cost(DEFAULT_COST); 9106 9107 format %{ "MULLW $dst, $src1, $src2" %} 9108 size(4); 9109 ins_encode %{ 9110 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9111 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9112 %} 9113 ins_pipe(pipe_class_default); 9114 %} 9115 9116 // Immediate Multiplication 9117 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9118 match(Set dst (MulI src1 src2)); 9119 ins_cost(DEFAULT_COST); 9120 9121 format %{ "MULLI $dst, $src1, $src2" %} 9122 size(4); 9123 ins_encode %{ 9124 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9125 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9126 %} 9127 ins_pipe(pipe_class_default); 9128 %} 9129 9130 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9131 match(Set dst (MulL src1 src2)); 9132 ins_cost(DEFAULT_COST); 9133 9134 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9135 size(4); 9136 ins_encode %{ 9137 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9138 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9139 %} 9140 ins_pipe(pipe_class_default); 9141 %} 9142 9143 // Multiply high for optimized long division by constant. 9144 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9145 match(Set dst (MulHiL src1 src2)); 9146 ins_cost(DEFAULT_COST); 9147 9148 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9149 size(4); 9150 ins_encode %{ 9151 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9152 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9153 %} 9154 ins_pipe(pipe_class_default); 9155 %} 9156 9157 // Immediate Multiplication 9158 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9159 match(Set dst (MulL src1 src2)); 9160 ins_cost(DEFAULT_COST); 9161 9162 format %{ "MULLI $dst, $src1, $src2" %} 9163 size(4); 9164 ins_encode %{ 9165 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9166 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9167 %} 9168 ins_pipe(pipe_class_default); 9169 %} 9170 9171 // Integer Division with Immediate -1: Negate. 9172 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9173 match(Set dst (DivI src1 src2)); 9174 ins_cost(DEFAULT_COST); 9175 9176 format %{ "NEG $dst, $src1 \t// /-1" %} 9177 size(4); 9178 ins_encode %{ 9179 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9180 __ neg($dst$$Register, $src1$$Register); 9181 %} 9182 ins_pipe(pipe_class_default); 9183 %} 9184 9185 // Integer Division with constant, but not -1. 9186 // We should be able to improve this by checking the type of src2. 9187 // It might well be that src2 is known to be positive. 9188 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9189 match(Set dst (DivI src1 src2)); 9190 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9191 ins_cost(2*DEFAULT_COST); 9192 9193 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9194 size(4); 9195 ins_encode %{ 9196 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9197 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9198 %} 9199 ins_pipe(pipe_class_default); 9200 %} 9201 9202 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9203 effect(USE_DEF dst, USE src1, USE crx); 9204 predicate(false); 9205 9206 ins_variable_size_depending_on_alignment(true); 9207 9208 format %{ "CMOVE $dst, neg($src1), $crx" %} 9209 // Worst case is branch + move + stop, no stop without scheduler. 9210 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9211 ins_encode %{ 9212 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9213 Label done; 9214 __ bne($crx$$CondRegister, done); 9215 __ neg($dst$$Register, $src1$$Register); 9216 // TODO PPC port __ endgroup_if_needed(_size == 12); 9217 __ bind(done); 9218 %} 9219 ins_pipe(pipe_class_default); 9220 %} 9221 9222 // Integer Division with Registers not containing constants. 9223 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9224 match(Set dst (DivI src1 src2)); 9225 ins_cost(10*DEFAULT_COST); 9226 9227 expand %{ 9228 immI16 imm %{ (int)-1 %} 9229 flagsReg tmp1; 9230 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9231 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9232 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9233 %} 9234 %} 9235 9236 // Long Division with Immediate -1: Negate. 9237 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9238 match(Set dst (DivL src1 src2)); 9239 ins_cost(DEFAULT_COST); 9240 9241 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9242 size(4); 9243 ins_encode %{ 9244 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9245 __ neg($dst$$Register, $src1$$Register); 9246 %} 9247 ins_pipe(pipe_class_default); 9248 %} 9249 9250 // Long Division with constant, but not -1. 9251 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9252 match(Set dst (DivL src1 src2)); 9253 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9254 ins_cost(2*DEFAULT_COST); 9255 9256 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9257 size(4); 9258 ins_encode %{ 9259 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9260 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9261 %} 9262 ins_pipe(pipe_class_default); 9263 %} 9264 9265 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9266 effect(USE_DEF dst, USE src1, USE crx); 9267 predicate(false); 9268 9269 ins_variable_size_depending_on_alignment(true); 9270 9271 format %{ "CMOVE $dst, neg($src1), $crx" %} 9272 // Worst case is branch + move + stop, no stop without scheduler. 9273 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9274 ins_encode %{ 9275 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9276 Label done; 9277 __ bne($crx$$CondRegister, done); 9278 __ neg($dst$$Register, $src1$$Register); 9279 // TODO PPC port __ endgroup_if_needed(_size == 12); 9280 __ bind(done); 9281 %} 9282 ins_pipe(pipe_class_default); 9283 %} 9284 9285 // Long Division with Registers not containing constants. 9286 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9287 match(Set dst (DivL src1 src2)); 9288 ins_cost(10*DEFAULT_COST); 9289 9290 expand %{ 9291 immL16 imm %{ (int)-1 %} 9292 flagsReg tmp1; 9293 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9294 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9295 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9296 %} 9297 %} 9298 9299 // Integer Remainder with registers. 9300 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9301 match(Set dst (ModI src1 src2)); 9302 ins_cost(10*DEFAULT_COST); 9303 9304 expand %{ 9305 immI16 imm %{ (int)-1 %} 9306 flagsReg tmp1; 9307 iRegIdst tmp2; 9308 iRegIdst tmp3; 9309 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9310 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9311 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9312 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9313 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9314 %} 9315 %} 9316 9317 // Long Remainder with registers 9318 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9319 match(Set dst (ModL src1 src2)); 9320 ins_cost(10*DEFAULT_COST); 9321 9322 expand %{ 9323 immL16 imm %{ (int)-1 %} 9324 flagsReg tmp1; 9325 iRegLdst tmp2; 9326 iRegLdst tmp3; 9327 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9328 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9329 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9330 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9331 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9332 %} 9333 %} 9334 9335 // Integer Shift Instructions 9336 9337 // Register Shift Left 9338 9339 // Clear all but the lowest #mask bits. 9340 // Used to normalize shift amounts in registers. 9341 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9342 // no match-rule, false predicate 9343 effect(DEF dst, USE src, USE mask); 9344 predicate(false); 9345 9346 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9347 size(4); 9348 ins_encode %{ 9349 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9350 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9351 %} 9352 ins_pipe(pipe_class_default); 9353 %} 9354 9355 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9356 // no match-rule, false predicate 9357 effect(DEF dst, USE src1, USE src2); 9358 predicate(false); 9359 9360 format %{ "SLW $dst, $src1, $src2" %} 9361 size(4); 9362 ins_encode %{ 9363 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9364 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9365 %} 9366 ins_pipe(pipe_class_default); 9367 %} 9368 9369 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9370 match(Set dst (LShiftI src1 src2)); 9371 ins_cost(DEFAULT_COST*2); 9372 expand %{ 9373 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9374 iRegIdst tmpI; 9375 maskI_reg_imm(tmpI, src2, mask); 9376 lShiftI_reg_reg(dst, src1, tmpI); 9377 %} 9378 %} 9379 9380 // Register Shift Left Immediate 9381 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9382 match(Set dst (LShiftI src1 src2)); 9383 9384 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9385 size(4); 9386 ins_encode %{ 9387 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9388 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9389 %} 9390 ins_pipe(pipe_class_default); 9391 %} 9392 9393 // AndI with negpow2-constant + LShiftI 9394 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9395 match(Set dst (LShiftI (AndI src1 src2) src3)); 9396 predicate(UseRotateAndMaskInstructionsPPC64); 9397 9398 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9399 size(4); 9400 ins_encode %{ 9401 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9402 long src2 = $src2$$constant; 9403 long src3 = $src3$$constant; 9404 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9405 if (maskbits >= 32) { 9406 __ li($dst$$Register, 0); // addi 9407 } else { 9408 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9409 } 9410 %} 9411 ins_pipe(pipe_class_default); 9412 %} 9413 9414 // RShiftI + AndI with negpow2-constant + LShiftI 9415 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9416 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9417 predicate(UseRotateAndMaskInstructionsPPC64); 9418 9419 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9420 size(4); 9421 ins_encode %{ 9422 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9423 long src2 = $src2$$constant; 9424 long src3 = $src3$$constant; 9425 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9426 if (maskbits >= 32) { 9427 __ li($dst$$Register, 0); // addi 9428 } else { 9429 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9430 } 9431 %} 9432 ins_pipe(pipe_class_default); 9433 %} 9434 9435 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9436 // no match-rule, false predicate 9437 effect(DEF dst, USE src1, USE src2); 9438 predicate(false); 9439 9440 format %{ "SLD $dst, $src1, $src2" %} 9441 size(4); 9442 ins_encode %{ 9443 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9444 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9445 %} 9446 ins_pipe(pipe_class_default); 9447 %} 9448 9449 // Register Shift Left 9450 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9451 match(Set dst (LShiftL src1 src2)); 9452 ins_cost(DEFAULT_COST*2); 9453 expand %{ 9454 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9455 iRegIdst tmpI; 9456 maskI_reg_imm(tmpI, src2, mask); 9457 lShiftL_regL_regI(dst, src1, tmpI); 9458 %} 9459 %} 9460 9461 // Register Shift Left Immediate 9462 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9463 match(Set dst (LShiftL src1 src2)); 9464 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9465 size(4); 9466 ins_encode %{ 9467 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9468 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9469 %} 9470 ins_pipe(pipe_class_default); 9471 %} 9472 9473 // If we shift more than 32 bits, we need not convert I2L. 9474 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9475 match(Set dst (LShiftL (ConvI2L src1) src2)); 9476 ins_cost(DEFAULT_COST); 9477 9478 size(4); 9479 format %{ "SLDI $dst, i2l($src1), $src2" %} 9480 ins_encode %{ 9481 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9482 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9483 %} 9484 ins_pipe(pipe_class_default); 9485 %} 9486 9487 // Shift a postivie int to the left. 9488 // Clrlsldi clears the upper 32 bits and shifts. 9489 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9490 match(Set dst (LShiftL (ConvI2L src1) src2)); 9491 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9492 9493 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9494 size(4); 9495 ins_encode %{ 9496 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9497 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9498 %} 9499 ins_pipe(pipe_class_default); 9500 %} 9501 9502 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9503 // no match-rule, false predicate 9504 effect(DEF dst, USE src1, USE src2); 9505 predicate(false); 9506 9507 format %{ "SRAW $dst, $src1, $src2" %} 9508 size(4); 9509 ins_encode %{ 9510 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9511 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9512 %} 9513 ins_pipe(pipe_class_default); 9514 %} 9515 9516 // Register Arithmetic Shift Right 9517 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9518 match(Set dst (RShiftI src1 src2)); 9519 ins_cost(DEFAULT_COST*2); 9520 expand %{ 9521 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9522 iRegIdst tmpI; 9523 maskI_reg_imm(tmpI, src2, mask); 9524 arShiftI_reg_reg(dst, src1, tmpI); 9525 %} 9526 %} 9527 9528 // Register Arithmetic Shift Right Immediate 9529 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9530 match(Set dst (RShiftI src1 src2)); 9531 9532 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9533 size(4); 9534 ins_encode %{ 9535 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9536 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9537 %} 9538 ins_pipe(pipe_class_default); 9539 %} 9540 9541 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9542 // no match-rule, false predicate 9543 effect(DEF dst, USE src1, USE src2); 9544 predicate(false); 9545 9546 format %{ "SRAD $dst, $src1, $src2" %} 9547 size(4); 9548 ins_encode %{ 9549 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9550 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9551 %} 9552 ins_pipe(pipe_class_default); 9553 %} 9554 9555 // Register Shift Right Arithmetic Long 9556 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9557 match(Set dst (RShiftL src1 src2)); 9558 ins_cost(DEFAULT_COST*2); 9559 9560 expand %{ 9561 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9562 iRegIdst tmpI; 9563 maskI_reg_imm(tmpI, src2, mask); 9564 arShiftL_regL_regI(dst, src1, tmpI); 9565 %} 9566 %} 9567 9568 // Register Shift Right Immediate 9569 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9570 match(Set dst (RShiftL src1 src2)); 9571 9572 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9573 size(4); 9574 ins_encode %{ 9575 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9576 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9577 %} 9578 ins_pipe(pipe_class_default); 9579 %} 9580 9581 // RShiftL + ConvL2I 9582 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9583 match(Set dst (ConvL2I (RShiftL src1 src2))); 9584 9585 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9586 size(4); 9587 ins_encode %{ 9588 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9589 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9590 %} 9591 ins_pipe(pipe_class_default); 9592 %} 9593 9594 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9595 // no match-rule, false predicate 9596 effect(DEF dst, USE src1, USE src2); 9597 predicate(false); 9598 9599 format %{ "SRW $dst, $src1, $src2" %} 9600 size(4); 9601 ins_encode %{ 9602 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9603 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9604 %} 9605 ins_pipe(pipe_class_default); 9606 %} 9607 9608 // Register Shift Right 9609 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9610 match(Set dst (URShiftI src1 src2)); 9611 ins_cost(DEFAULT_COST*2); 9612 9613 expand %{ 9614 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9615 iRegIdst tmpI; 9616 maskI_reg_imm(tmpI, src2, mask); 9617 urShiftI_reg_reg(dst, src1, tmpI); 9618 %} 9619 %} 9620 9621 // Register Shift Right Immediate 9622 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9623 match(Set dst (URShiftI src1 src2)); 9624 9625 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9626 size(4); 9627 ins_encode %{ 9628 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9629 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9630 %} 9631 ins_pipe(pipe_class_default); 9632 %} 9633 9634 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9635 // no match-rule, false predicate 9636 effect(DEF dst, USE src1, USE src2); 9637 predicate(false); 9638 9639 format %{ "SRD $dst, $src1, $src2" %} 9640 size(4); 9641 ins_encode %{ 9642 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9643 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9644 %} 9645 ins_pipe(pipe_class_default); 9646 %} 9647 9648 // Register Shift Right 9649 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9650 match(Set dst (URShiftL src1 src2)); 9651 ins_cost(DEFAULT_COST*2); 9652 9653 expand %{ 9654 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9655 iRegIdst tmpI; 9656 maskI_reg_imm(tmpI, src2, mask); 9657 urShiftL_regL_regI(dst, src1, tmpI); 9658 %} 9659 %} 9660 9661 // Register Shift Right Immediate 9662 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9663 match(Set dst (URShiftL src1 src2)); 9664 9665 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9666 size(4); 9667 ins_encode %{ 9668 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9669 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9670 %} 9671 ins_pipe(pipe_class_default); 9672 %} 9673 9674 // URShiftL + ConvL2I. 9675 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9676 match(Set dst (ConvL2I (URShiftL src1 src2))); 9677 9678 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9679 size(4); 9680 ins_encode %{ 9681 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9682 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9683 %} 9684 ins_pipe(pipe_class_default); 9685 %} 9686 9687 // Register Shift Right Immediate with a CastP2X 9688 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9689 match(Set dst (URShiftL (CastP2X src1) src2)); 9690 9691 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9692 size(4); 9693 ins_encode %{ 9694 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9695 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9696 %} 9697 ins_pipe(pipe_class_default); 9698 %} 9699 9700 // Bitfield Extract: URShiftI + AndI 9701 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9702 match(Set dst (AndI (URShiftI src1 src2) src3)); 9703 9704 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9705 size(4); 9706 ins_encode %{ 9707 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9708 int rshift = ($src2$$constant) & 0x1f; 9709 int length = log2_long(((jlong) $src3$$constant) + 1); 9710 if (rshift + length > 32) { 9711 // if necessary, adjust mask to omit rotated bits. 9712 length = 32 - rshift; 9713 } 9714 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9715 %} 9716 ins_pipe(pipe_class_default); 9717 %} 9718 9719 // Bitfield Extract: URShiftL + AndL 9720 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9721 match(Set dst (AndL (URShiftL src1 src2) src3)); 9722 9723 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9724 size(4); 9725 ins_encode %{ 9726 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9727 int rshift = ($src2$$constant) & 0x3f; 9728 int length = log2_long(((jlong) $src3$$constant) + 1); 9729 if (rshift + length > 64) { 9730 // if necessary, adjust mask to omit rotated bits. 9731 length = 64 - rshift; 9732 } 9733 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9734 %} 9735 ins_pipe(pipe_class_default); 9736 %} 9737 9738 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9739 match(Set dst (ConvL2I (ConvI2L src))); 9740 9741 format %{ "EXTSW $dst, $src \t// int->int" %} 9742 size(4); 9743 ins_encode %{ 9744 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9745 __ extsw($dst$$Register, $src$$Register); 9746 %} 9747 ins_pipe(pipe_class_default); 9748 %} 9749 9750 //----------Rotate Instructions------------------------------------------------ 9751 9752 // Rotate Left by 8-bit immediate 9753 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9754 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9755 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9756 9757 format %{ "ROTLWI $dst, $src, $lshift" %} 9758 size(4); 9759 ins_encode %{ 9760 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9761 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9762 %} 9763 ins_pipe(pipe_class_default); 9764 %} 9765 9766 // Rotate Right by 8-bit immediate 9767 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9768 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9769 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9770 9771 format %{ "ROTRWI $dst, $rshift" %} 9772 size(4); 9773 ins_encode %{ 9774 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9775 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9776 %} 9777 ins_pipe(pipe_class_default); 9778 %} 9779 9780 //----------Floating Point Arithmetic Instructions----------------------------- 9781 9782 // Add float single precision 9783 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9784 match(Set dst (AddF src1 src2)); 9785 9786 format %{ "FADDS $dst, $src1, $src2" %} 9787 size(4); 9788 ins_encode %{ 9789 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9790 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9791 %} 9792 ins_pipe(pipe_class_default); 9793 %} 9794 9795 // Add float double precision 9796 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9797 match(Set dst (AddD src1 src2)); 9798 9799 format %{ "FADD $dst, $src1, $src2" %} 9800 size(4); 9801 ins_encode %{ 9802 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9803 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9804 %} 9805 ins_pipe(pipe_class_default); 9806 %} 9807 9808 // Sub float single precision 9809 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9810 match(Set dst (SubF src1 src2)); 9811 9812 format %{ "FSUBS $dst, $src1, $src2" %} 9813 size(4); 9814 ins_encode %{ 9815 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9816 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9817 %} 9818 ins_pipe(pipe_class_default); 9819 %} 9820 9821 // Sub float double precision 9822 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9823 match(Set dst (SubD src1 src2)); 9824 format %{ "FSUB $dst, $src1, $src2" %} 9825 size(4); 9826 ins_encode %{ 9827 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9828 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9829 %} 9830 ins_pipe(pipe_class_default); 9831 %} 9832 9833 // Mul float single precision 9834 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9835 match(Set dst (MulF src1 src2)); 9836 format %{ "FMULS $dst, $src1, $src2" %} 9837 size(4); 9838 ins_encode %{ 9839 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9840 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9841 %} 9842 ins_pipe(pipe_class_default); 9843 %} 9844 9845 // Mul float double precision 9846 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9847 match(Set dst (MulD src1 src2)); 9848 format %{ "FMUL $dst, $src1, $src2" %} 9849 size(4); 9850 ins_encode %{ 9851 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9852 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9853 %} 9854 ins_pipe(pipe_class_default); 9855 %} 9856 9857 // Div float single precision 9858 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9859 match(Set dst (DivF src1 src2)); 9860 format %{ "FDIVS $dst, $src1, $src2" %} 9861 size(4); 9862 ins_encode %{ 9863 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9864 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9865 %} 9866 ins_pipe(pipe_class_default); 9867 %} 9868 9869 // Div float double precision 9870 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9871 match(Set dst (DivD src1 src2)); 9872 format %{ "FDIV $dst, $src1, $src2" %} 9873 size(4); 9874 ins_encode %{ 9875 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9876 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9877 %} 9878 ins_pipe(pipe_class_default); 9879 %} 9880 9881 // Absolute float single precision 9882 instruct absF_reg(regF dst, regF src) %{ 9883 match(Set dst (AbsF src)); 9884 format %{ "FABS $dst, $src \t// float" %} 9885 size(4); 9886 ins_encode %{ 9887 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9888 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9889 %} 9890 ins_pipe(pipe_class_default); 9891 %} 9892 9893 // Absolute float double precision 9894 instruct absD_reg(regD dst, regD src) %{ 9895 match(Set dst (AbsD src)); 9896 format %{ "FABS $dst, $src \t// double" %} 9897 size(4); 9898 ins_encode %{ 9899 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9900 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9901 %} 9902 ins_pipe(pipe_class_default); 9903 %} 9904 9905 instruct negF_reg(regF dst, regF src) %{ 9906 match(Set dst (NegF src)); 9907 format %{ "FNEG $dst, $src \t// float" %} 9908 size(4); 9909 ins_encode %{ 9910 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9911 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9912 %} 9913 ins_pipe(pipe_class_default); 9914 %} 9915 9916 instruct negD_reg(regD dst, regD src) %{ 9917 match(Set dst (NegD src)); 9918 format %{ "FNEG $dst, $src \t// double" %} 9919 size(4); 9920 ins_encode %{ 9921 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9922 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9923 %} 9924 ins_pipe(pipe_class_default); 9925 %} 9926 9927 // AbsF + NegF. 9928 instruct negF_absF_reg(regF dst, regF src) %{ 9929 match(Set dst (NegF (AbsF src))); 9930 format %{ "FNABS $dst, $src \t// float" %} 9931 size(4); 9932 ins_encode %{ 9933 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9934 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9935 %} 9936 ins_pipe(pipe_class_default); 9937 %} 9938 9939 // AbsD + NegD. 9940 instruct negD_absD_reg(regD dst, regD src) %{ 9941 match(Set dst (NegD (AbsD src))); 9942 format %{ "FNABS $dst, $src \t// double" %} 9943 size(4); 9944 ins_encode %{ 9945 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9946 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9947 %} 9948 ins_pipe(pipe_class_default); 9949 %} 9950 9951 // VM_Version::has_fsqrt() decides if this node will be used. 9952 // Sqrt float double precision 9953 instruct sqrtD_reg(regD dst, regD src) %{ 9954 match(Set dst (SqrtD src)); 9955 format %{ "FSQRT $dst, $src" %} 9956 size(4); 9957 ins_encode %{ 9958 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9959 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9960 %} 9961 ins_pipe(pipe_class_default); 9962 %} 9963 9964 // Single-precision sqrt. 9965 instruct sqrtF_reg(regF dst, regF src) %{ 9966 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9967 predicate(VM_Version::has_fsqrts()); 9968 ins_cost(DEFAULT_COST); 9969 9970 format %{ "FSQRTS $dst, $src" %} 9971 size(4); 9972 ins_encode %{ 9973 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9974 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9975 %} 9976 ins_pipe(pipe_class_default); 9977 %} 9978 9979 instruct roundDouble_nop(regD dst) %{ 9980 match(Set dst (RoundDouble dst)); 9981 ins_cost(0); 9982 9983 format %{ " -- \t// RoundDouble not needed - empty" %} 9984 size(0); 9985 // PPC results are already "rounded" (i.e., normal-format IEEE). 9986 ins_encode( /*empty*/ ); 9987 ins_pipe(pipe_class_default); 9988 %} 9989 9990 instruct roundFloat_nop(regF dst) %{ 9991 match(Set dst (RoundFloat dst)); 9992 ins_cost(0); 9993 9994 format %{ " -- \t// RoundFloat not needed - empty" %} 9995 size(0); 9996 // PPC results are already "rounded" (i.e., normal-format IEEE). 9997 ins_encode( /*empty*/ ); 9998 ins_pipe(pipe_class_default); 9999 %} 10000 10001 10002 // Multiply-Accumulate 10003 // src1 * src2 + src3 10004 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10005 match(Set dst (FmaF src3 (Binary src1 src2))); 10006 10007 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10008 size(4); 10009 ins_encode %{ 10010 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10011 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10012 %} 10013 ins_pipe(pipe_class_default); 10014 %} 10015 10016 // src1 * src2 + src3 10017 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10018 match(Set dst (FmaD src3 (Binary src1 src2))); 10019 10020 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10021 size(4); 10022 ins_encode %{ 10023 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10024 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10025 %} 10026 ins_pipe(pipe_class_default); 10027 %} 10028 10029 // -src1 * src2 + src3 = -(src1*src2-src3) 10030 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10031 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10032 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10033 10034 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10035 size(4); 10036 ins_encode %{ 10037 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10038 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10039 %} 10040 ins_pipe(pipe_class_default); 10041 %} 10042 10043 // -src1 * src2 + src3 = -(src1*src2-src3) 10044 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10045 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10046 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10047 10048 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10049 size(4); 10050 ins_encode %{ 10051 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10052 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10053 %} 10054 ins_pipe(pipe_class_default); 10055 %} 10056 10057 // -src1 * src2 - src3 = -(src1*src2+src3) 10058 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10059 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10060 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10061 10062 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10063 size(4); 10064 ins_encode %{ 10065 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10066 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10067 %} 10068 ins_pipe(pipe_class_default); 10069 %} 10070 10071 // -src1 * src2 - src3 = -(src1*src2+src3) 10072 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10073 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10074 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10075 10076 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10077 size(4); 10078 ins_encode %{ 10079 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10080 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10081 %} 10082 ins_pipe(pipe_class_default); 10083 %} 10084 10085 // src1 * src2 - src3 10086 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10087 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10088 10089 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10090 size(4); 10091 ins_encode %{ 10092 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10093 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10094 %} 10095 ins_pipe(pipe_class_default); 10096 %} 10097 10098 // src1 * src2 - src3 10099 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10100 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10101 10102 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10103 size(4); 10104 ins_encode %{ 10105 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10106 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10107 %} 10108 ins_pipe(pipe_class_default); 10109 %} 10110 10111 10112 //----------Logical Instructions----------------------------------------------- 10113 10114 // And Instructions 10115 10116 // Register And 10117 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10118 match(Set dst (AndI src1 src2)); 10119 format %{ "AND $dst, $src1, $src2" %} 10120 size(4); 10121 ins_encode %{ 10122 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10123 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10124 %} 10125 ins_pipe(pipe_class_default); 10126 %} 10127 10128 // Left shifted Immediate And 10129 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10130 match(Set dst (AndI src1 src2)); 10131 effect(KILL cr0); 10132 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10133 size(4); 10134 ins_encode %{ 10135 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10136 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10137 %} 10138 ins_pipe(pipe_class_default); 10139 %} 10140 10141 // Immediate And 10142 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10143 match(Set dst (AndI src1 src2)); 10144 effect(KILL cr0); 10145 10146 format %{ "ANDI $dst, $src1, $src2" %} 10147 size(4); 10148 ins_encode %{ 10149 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10150 // FIXME: avoid andi_ ? 10151 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10152 %} 10153 ins_pipe(pipe_class_default); 10154 %} 10155 10156 // Immediate And where the immediate is a negative power of 2. 10157 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10158 match(Set dst (AndI src1 src2)); 10159 format %{ "ANDWI $dst, $src1, $src2" %} 10160 size(4); 10161 ins_encode %{ 10162 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10163 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10164 %} 10165 ins_pipe(pipe_class_default); 10166 %} 10167 10168 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10169 match(Set dst (AndI src1 src2)); 10170 format %{ "ANDWI $dst, $src1, $src2" %} 10171 size(4); 10172 ins_encode %{ 10173 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10174 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10175 %} 10176 ins_pipe(pipe_class_default); 10177 %} 10178 10179 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10180 match(Set dst (AndI src1 src2)); 10181 predicate(UseRotateAndMaskInstructionsPPC64); 10182 format %{ "ANDWI $dst, $src1, $src2" %} 10183 size(4); 10184 ins_encode %{ 10185 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10186 __ rlwinm($dst$$Register, $src1$$Register, 0, 10187 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10188 %} 10189 ins_pipe(pipe_class_default); 10190 %} 10191 10192 // Register And Long 10193 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10194 match(Set dst (AndL src1 src2)); 10195 ins_cost(DEFAULT_COST); 10196 10197 format %{ "AND $dst, $src1, $src2 \t// long" %} 10198 size(4); 10199 ins_encode %{ 10200 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10201 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10202 %} 10203 ins_pipe(pipe_class_default); 10204 %} 10205 10206 // Immediate And long 10207 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10208 match(Set dst (AndL src1 src2)); 10209 effect(KILL cr0); 10210 10211 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10212 size(4); 10213 ins_encode %{ 10214 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10215 // FIXME: avoid andi_ ? 10216 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10217 %} 10218 ins_pipe(pipe_class_default); 10219 %} 10220 10221 // Immediate And Long where the immediate is a negative power of 2. 10222 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10223 match(Set dst (AndL src1 src2)); 10224 format %{ "ANDDI $dst, $src1, $src2" %} 10225 size(4); 10226 ins_encode %{ 10227 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10228 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10229 %} 10230 ins_pipe(pipe_class_default); 10231 %} 10232 10233 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10234 match(Set dst (AndL src1 src2)); 10235 format %{ "ANDDI $dst, $src1, $src2" %} 10236 size(4); 10237 ins_encode %{ 10238 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10239 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10240 %} 10241 ins_pipe(pipe_class_default); 10242 %} 10243 10244 // AndL + ConvL2I. 10245 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10246 match(Set dst (ConvL2I (AndL src1 src2))); 10247 ins_cost(DEFAULT_COST); 10248 10249 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10250 size(4); 10251 ins_encode %{ 10252 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10253 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10254 %} 10255 ins_pipe(pipe_class_default); 10256 %} 10257 10258 // Or Instructions 10259 10260 // Register Or 10261 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10262 match(Set dst (OrI src1 src2)); 10263 format %{ "OR $dst, $src1, $src2" %} 10264 size(4); 10265 ins_encode %{ 10266 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10267 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10268 %} 10269 ins_pipe(pipe_class_default); 10270 %} 10271 10272 // Expand does not work with above instruct. (??) 10273 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10274 // no match-rule 10275 effect(DEF dst, USE src1, USE src2); 10276 format %{ "OR $dst, $src1, $src2" %} 10277 size(4); 10278 ins_encode %{ 10279 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10280 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10281 %} 10282 ins_pipe(pipe_class_default); 10283 %} 10284 10285 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10286 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10287 ins_cost(DEFAULT_COST*3); 10288 10289 expand %{ 10290 // FIXME: we should do this in the ideal world. 10291 iRegIdst tmp1; 10292 iRegIdst tmp2; 10293 orI_reg_reg(tmp1, src1, src2); 10294 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10295 orI_reg_reg(dst, tmp1, tmp2); 10296 %} 10297 %} 10298 10299 // Immediate Or 10300 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10301 match(Set dst (OrI src1 src2)); 10302 format %{ "ORI $dst, $src1, $src2" %} 10303 size(4); 10304 ins_encode %{ 10305 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10306 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10307 %} 10308 ins_pipe(pipe_class_default); 10309 %} 10310 10311 // Register Or Long 10312 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10313 match(Set dst (OrL src1 src2)); 10314 ins_cost(DEFAULT_COST); 10315 10316 size(4); 10317 format %{ "OR $dst, $src1, $src2 \t// long" %} 10318 ins_encode %{ 10319 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10320 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10321 %} 10322 ins_pipe(pipe_class_default); 10323 %} 10324 10325 // OrL + ConvL2I. 10326 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10327 match(Set dst (ConvL2I (OrL src1 src2))); 10328 ins_cost(DEFAULT_COST); 10329 10330 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10331 size(4); 10332 ins_encode %{ 10333 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10334 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10335 %} 10336 ins_pipe(pipe_class_default); 10337 %} 10338 10339 // Immediate Or long 10340 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10341 match(Set dst (OrL src1 con)); 10342 ins_cost(DEFAULT_COST); 10343 10344 format %{ "ORI $dst, $src1, $con \t// long" %} 10345 size(4); 10346 ins_encode %{ 10347 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10348 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10349 %} 10350 ins_pipe(pipe_class_default); 10351 %} 10352 10353 // Xor Instructions 10354 10355 // Register Xor 10356 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10357 match(Set dst (XorI src1 src2)); 10358 format %{ "XOR $dst, $src1, $src2" %} 10359 size(4); 10360 ins_encode %{ 10361 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10362 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10363 %} 10364 ins_pipe(pipe_class_default); 10365 %} 10366 10367 // Expand does not work with above instruct. (??) 10368 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10369 // no match-rule 10370 effect(DEF dst, USE src1, USE src2); 10371 format %{ "XOR $dst, $src1, $src2" %} 10372 size(4); 10373 ins_encode %{ 10374 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10375 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10376 %} 10377 ins_pipe(pipe_class_default); 10378 %} 10379 10380 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10381 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10382 ins_cost(DEFAULT_COST*3); 10383 10384 expand %{ 10385 // FIXME: we should do this in the ideal world. 10386 iRegIdst tmp1; 10387 iRegIdst tmp2; 10388 xorI_reg_reg(tmp1, src1, src2); 10389 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10390 xorI_reg_reg(dst, tmp1, tmp2); 10391 %} 10392 %} 10393 10394 // Immediate Xor 10395 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10396 match(Set dst (XorI src1 src2)); 10397 format %{ "XORI $dst, $src1, $src2" %} 10398 size(4); 10399 ins_encode %{ 10400 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10401 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10402 %} 10403 ins_pipe(pipe_class_default); 10404 %} 10405 10406 // Register Xor Long 10407 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10408 match(Set dst (XorL src1 src2)); 10409 ins_cost(DEFAULT_COST); 10410 10411 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10412 size(4); 10413 ins_encode %{ 10414 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10415 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10416 %} 10417 ins_pipe(pipe_class_default); 10418 %} 10419 10420 // XorL + ConvL2I. 10421 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10422 match(Set dst (ConvL2I (XorL src1 src2))); 10423 ins_cost(DEFAULT_COST); 10424 10425 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10426 size(4); 10427 ins_encode %{ 10428 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10429 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10430 %} 10431 ins_pipe(pipe_class_default); 10432 %} 10433 10434 // Immediate Xor Long 10435 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10436 match(Set dst (XorL src1 src2)); 10437 ins_cost(DEFAULT_COST); 10438 10439 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10440 size(4); 10441 ins_encode %{ 10442 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10443 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10444 %} 10445 ins_pipe(pipe_class_default); 10446 %} 10447 10448 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10449 match(Set dst (XorI src1 src2)); 10450 ins_cost(DEFAULT_COST); 10451 10452 format %{ "NOT $dst, $src1 ($src2)" %} 10453 size(4); 10454 ins_encode %{ 10455 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10456 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10457 %} 10458 ins_pipe(pipe_class_default); 10459 %} 10460 10461 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10462 match(Set dst (XorL src1 src2)); 10463 ins_cost(DEFAULT_COST); 10464 10465 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10466 size(4); 10467 ins_encode %{ 10468 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10469 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10470 %} 10471 ins_pipe(pipe_class_default); 10472 %} 10473 10474 // And-complement 10475 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10476 match(Set dst (AndI (XorI src1 src2) src3)); 10477 ins_cost(DEFAULT_COST); 10478 10479 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10480 size(4); 10481 ins_encode( enc_andc(dst, src3, src1) ); 10482 ins_pipe(pipe_class_default); 10483 %} 10484 10485 // And-complement 10486 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10487 // no match-rule, false predicate 10488 effect(DEF dst, USE src1, USE src2); 10489 predicate(false); 10490 10491 format %{ "ANDC $dst, $src1, $src2" %} 10492 size(4); 10493 ins_encode %{ 10494 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10495 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10496 %} 10497 ins_pipe(pipe_class_default); 10498 %} 10499 10500 //----------Moves between int/long and float/double---------------------------- 10501 // 10502 // The following rules move values from int/long registers/stack-locations 10503 // to float/double registers/stack-locations and vice versa, without doing any 10504 // conversions. These rules are used to implement the bit-conversion methods 10505 // of java.lang.Float etc., e.g. 10506 // int floatToIntBits(float value) 10507 // float intBitsToFloat(int bits) 10508 // 10509 // Notes on the implementation on ppc64: 10510 // For Power7 and earlier, the rules are limited to those which move between a 10511 // register and a stack-location, because we always have to go through memory 10512 // when moving between a float register and an integer register. 10513 // This restriction is removed in Power8 with the introduction of the mtfprd 10514 // and mffprd instructions. 10515 10516 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10517 match(Set dst (MoveL2D src)); 10518 predicate(VM_Version::has_mtfprd()); 10519 10520 format %{ "MTFPRD $dst, $src" %} 10521 size(4); 10522 ins_encode %{ 10523 __ mtfprd($dst$$FloatRegister, $src$$Register); 10524 %} 10525 ins_pipe(pipe_class_default); 10526 %} 10527 10528 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10529 // no match-rule, false predicate 10530 effect(DEF dst, USE src); 10531 predicate(false); 10532 10533 format %{ "MTFPRWA $dst, $src" %} 10534 size(4); 10535 ins_encode %{ 10536 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10537 %} 10538 ins_pipe(pipe_class_default); 10539 %} 10540 10541 //---------- Chain stack slots between similar types -------- 10542 10543 // These are needed so that the rules below can match. 10544 10545 // Load integer from stack slot 10546 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10547 match(Set dst src); 10548 ins_cost(MEMORY_REF_COST); 10549 10550 format %{ "LWZ $dst, $src" %} 10551 size(4); 10552 ins_encode( enc_lwz(dst, src) ); 10553 ins_pipe(pipe_class_memory); 10554 %} 10555 10556 // Store integer to stack slot 10557 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10558 match(Set dst src); 10559 ins_cost(MEMORY_REF_COST); 10560 10561 format %{ "STW $src, $dst \t// stk" %} 10562 size(4); 10563 ins_encode( enc_stw(src, dst) ); // rs=rt 10564 ins_pipe(pipe_class_memory); 10565 %} 10566 10567 // Load long from stack slot 10568 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10569 match(Set dst src); 10570 ins_cost(MEMORY_REF_COST); 10571 10572 format %{ "LD $dst, $src \t// long" %} 10573 size(4); 10574 ins_encode( enc_ld(dst, src) ); 10575 ins_pipe(pipe_class_memory); 10576 %} 10577 10578 // Store long to stack slot 10579 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10580 match(Set dst src); 10581 ins_cost(MEMORY_REF_COST); 10582 10583 format %{ "STD $src, $dst \t// long" %} 10584 size(4); 10585 ins_encode( enc_std(src, dst) ); // rs=rt 10586 ins_pipe(pipe_class_memory); 10587 %} 10588 10589 //----------Moves between int and float 10590 10591 // Move float value from float stack-location to integer register. 10592 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10593 match(Set dst (MoveF2I src)); 10594 ins_cost(MEMORY_REF_COST); 10595 10596 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10597 size(4); 10598 ins_encode( enc_lwz(dst, src) ); 10599 ins_pipe(pipe_class_memory); 10600 %} 10601 10602 // Move float value from float register to integer stack-location. 10603 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10604 match(Set dst (MoveF2I src)); 10605 ins_cost(MEMORY_REF_COST); 10606 10607 format %{ "STFS $src, $dst \t// MoveF2I" %} 10608 size(4); 10609 ins_encode( enc_stfs(src, dst) ); 10610 ins_pipe(pipe_class_memory); 10611 %} 10612 10613 // Move integer value from integer stack-location to float register. 10614 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10615 match(Set dst (MoveI2F src)); 10616 ins_cost(MEMORY_REF_COST); 10617 10618 format %{ "LFS $dst, $src \t// MoveI2F" %} 10619 size(4); 10620 ins_encode %{ 10621 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10622 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10623 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10624 %} 10625 ins_pipe(pipe_class_memory); 10626 %} 10627 10628 // Move integer value from integer register to float stack-location. 10629 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10630 match(Set dst (MoveI2F src)); 10631 ins_cost(MEMORY_REF_COST); 10632 10633 format %{ "STW $src, $dst \t// MoveI2F" %} 10634 size(4); 10635 ins_encode( enc_stw(src, dst) ); 10636 ins_pipe(pipe_class_memory); 10637 %} 10638 10639 //----------Moves between long and float 10640 10641 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10642 // no match-rule, false predicate 10643 effect(DEF dst, USE src); 10644 predicate(false); 10645 10646 format %{ "storeD $src, $dst \t// STACK" %} 10647 size(4); 10648 ins_encode( enc_stfd(src, dst) ); 10649 ins_pipe(pipe_class_default); 10650 %} 10651 10652 //----------Moves between long and double 10653 10654 // Move double value from double stack-location to long register. 10655 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10656 match(Set dst (MoveD2L src)); 10657 ins_cost(MEMORY_REF_COST); 10658 size(4); 10659 format %{ "LD $dst, $src \t// MoveD2L" %} 10660 ins_encode( enc_ld(dst, src) ); 10661 ins_pipe(pipe_class_memory); 10662 %} 10663 10664 // Move double value from double register to long stack-location. 10665 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10666 match(Set dst (MoveD2L src)); 10667 effect(DEF dst, USE src); 10668 ins_cost(MEMORY_REF_COST); 10669 10670 format %{ "STFD $src, $dst \t// MoveD2L" %} 10671 size(4); 10672 ins_encode( enc_stfd(src, dst) ); 10673 ins_pipe(pipe_class_memory); 10674 %} 10675 10676 // Move long value from long stack-location to double register. 10677 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10678 match(Set dst (MoveL2D src)); 10679 ins_cost(MEMORY_REF_COST); 10680 10681 format %{ "LFD $dst, $src \t// MoveL2D" %} 10682 size(4); 10683 ins_encode( enc_lfd(dst, src) ); 10684 ins_pipe(pipe_class_memory); 10685 %} 10686 10687 // Move long value from long register to double stack-location. 10688 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10689 match(Set dst (MoveL2D src)); 10690 ins_cost(MEMORY_REF_COST); 10691 10692 format %{ "STD $src, $dst \t// MoveL2D" %} 10693 size(4); 10694 ins_encode( enc_std(src, dst) ); 10695 ins_pipe(pipe_class_memory); 10696 %} 10697 10698 //----------Register Move Instructions----------------------------------------- 10699 10700 // Replicate for Superword 10701 10702 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10703 predicate(false); 10704 effect(DEF dst, USE src); 10705 10706 format %{ "MR $dst, $src \t// replicate " %} 10707 // variable size, 0 or 4. 10708 ins_encode %{ 10709 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10710 __ mr_if_needed($dst$$Register, $src$$Register); 10711 %} 10712 ins_pipe(pipe_class_default); 10713 %} 10714 10715 //----------Cast instructions (Java-level type cast)--------------------------- 10716 10717 // Cast Long to Pointer for unsafe natives. 10718 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10719 match(Set dst (CastX2P src)); 10720 10721 format %{ "MR $dst, $src \t// Long->Ptr" %} 10722 // variable size, 0 or 4. 10723 ins_encode %{ 10724 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10725 __ mr_if_needed($dst$$Register, $src$$Register); 10726 %} 10727 ins_pipe(pipe_class_default); 10728 %} 10729 10730 // Cast Pointer to Long for unsafe natives. 10731 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10732 match(Set dst (CastP2X src)); 10733 10734 format %{ "MR $dst, $src \t// Ptr->Long" %} 10735 // variable size, 0 or 4. 10736 ins_encode %{ 10737 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10738 __ mr_if_needed($dst$$Register, $src$$Register); 10739 %} 10740 ins_pipe(pipe_class_default); 10741 %} 10742 10743 instruct castPP(iRegPdst dst) %{ 10744 match(Set dst (CastPP dst)); 10745 format %{ " -- \t// castPP of $dst" %} 10746 size(0); 10747 ins_encode( /*empty*/ ); 10748 ins_pipe(pipe_class_default); 10749 %} 10750 10751 instruct castII(iRegIdst dst) %{ 10752 match(Set dst (CastII dst)); 10753 format %{ " -- \t// castII of $dst" %} 10754 size(0); 10755 ins_encode( /*empty*/ ); 10756 ins_pipe(pipe_class_default); 10757 %} 10758 10759 instruct checkCastPP(iRegPdst dst) %{ 10760 match(Set dst (CheckCastPP dst)); 10761 format %{ " -- \t// checkcastPP of $dst" %} 10762 size(0); 10763 ins_encode( /*empty*/ ); 10764 ins_pipe(pipe_class_default); 10765 %} 10766 10767 //----------Convert instructions----------------------------------------------- 10768 10769 // Convert to boolean. 10770 10771 // int_to_bool(src) : { 1 if src != 0 10772 // { 0 else 10773 // 10774 // strategy: 10775 // 1) Count leading zeros of 32 bit-value src, 10776 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10777 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10778 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10779 10780 // convI2Bool 10781 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10782 match(Set dst (Conv2B src)); 10783 predicate(UseCountLeadingZerosInstructionsPPC64); 10784 ins_cost(DEFAULT_COST); 10785 10786 expand %{ 10787 immI shiftAmount %{ 0x5 %} 10788 uimmI16 mask %{ 0x1 %} 10789 iRegIdst tmp1; 10790 iRegIdst tmp2; 10791 countLeadingZerosI(tmp1, src); 10792 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10793 xorI_reg_uimm16(dst, tmp2, mask); 10794 %} 10795 %} 10796 10797 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10798 match(Set dst (Conv2B src)); 10799 effect(TEMP crx); 10800 predicate(!UseCountLeadingZerosInstructionsPPC64); 10801 ins_cost(DEFAULT_COST); 10802 10803 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10804 "LI $dst, #0\n\t" 10805 "BEQ $crx, done\n\t" 10806 "LI $dst, #1\n" 10807 "done:" %} 10808 size(16); 10809 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10810 ins_pipe(pipe_class_compare); 10811 %} 10812 10813 // ConvI2B + XorI 10814 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10815 match(Set dst (XorI (Conv2B src) mask)); 10816 predicate(UseCountLeadingZerosInstructionsPPC64); 10817 ins_cost(DEFAULT_COST); 10818 10819 expand %{ 10820 immI shiftAmount %{ 0x5 %} 10821 iRegIdst tmp1; 10822 countLeadingZerosI(tmp1, src); 10823 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10824 %} 10825 %} 10826 10827 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10828 match(Set dst (XorI (Conv2B src) mask)); 10829 effect(TEMP crx); 10830 predicate(!UseCountLeadingZerosInstructionsPPC64); 10831 ins_cost(DEFAULT_COST); 10832 10833 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10834 "LI $dst, #1\n\t" 10835 "BEQ $crx, done\n\t" 10836 "LI $dst, #0\n" 10837 "done:" %} 10838 size(16); 10839 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10840 ins_pipe(pipe_class_compare); 10841 %} 10842 10843 // AndI 0b0..010..0 + ConvI2B 10844 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10845 match(Set dst (Conv2B (AndI src mask))); 10846 predicate(UseRotateAndMaskInstructionsPPC64); 10847 ins_cost(DEFAULT_COST); 10848 10849 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10850 size(4); 10851 ins_encode %{ 10852 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10853 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10854 %} 10855 ins_pipe(pipe_class_default); 10856 %} 10857 10858 // Convert pointer to boolean. 10859 // 10860 // ptr_to_bool(src) : { 1 if src != 0 10861 // { 0 else 10862 // 10863 // strategy: 10864 // 1) Count leading zeros of 64 bit-value src, 10865 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10866 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10867 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10868 10869 // ConvP2B 10870 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10871 match(Set dst (Conv2B src)); 10872 predicate(UseCountLeadingZerosInstructionsPPC64); 10873 ins_cost(DEFAULT_COST); 10874 10875 expand %{ 10876 immI shiftAmount %{ 0x6 %} 10877 uimmI16 mask %{ 0x1 %} 10878 iRegIdst tmp1; 10879 iRegIdst tmp2; 10880 countLeadingZerosP(tmp1, src); 10881 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10882 xorI_reg_uimm16(dst, tmp2, mask); 10883 %} 10884 %} 10885 10886 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10887 match(Set dst (Conv2B src)); 10888 effect(TEMP crx); 10889 predicate(!UseCountLeadingZerosInstructionsPPC64); 10890 ins_cost(DEFAULT_COST); 10891 10892 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10893 "LI $dst, #0\n\t" 10894 "BEQ $crx, done\n\t" 10895 "LI $dst, #1\n" 10896 "done:" %} 10897 size(16); 10898 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10899 ins_pipe(pipe_class_compare); 10900 %} 10901 10902 // ConvP2B + XorI 10903 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10904 match(Set dst (XorI (Conv2B src) mask)); 10905 predicate(UseCountLeadingZerosInstructionsPPC64); 10906 ins_cost(DEFAULT_COST); 10907 10908 expand %{ 10909 immI shiftAmount %{ 0x6 %} 10910 iRegIdst tmp1; 10911 countLeadingZerosP(tmp1, src); 10912 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10913 %} 10914 %} 10915 10916 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10917 match(Set dst (XorI (Conv2B src) mask)); 10918 effect(TEMP crx); 10919 predicate(!UseCountLeadingZerosInstructionsPPC64); 10920 ins_cost(DEFAULT_COST); 10921 10922 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10923 "LI $dst, #1\n\t" 10924 "BEQ $crx, done\n\t" 10925 "LI $dst, #0\n" 10926 "done:" %} 10927 size(16); 10928 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10929 ins_pipe(pipe_class_compare); 10930 %} 10931 10932 // if src1 < src2, return -1 else return 0 10933 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10934 match(Set dst (CmpLTMask src1 src2)); 10935 ins_cost(DEFAULT_COST*4); 10936 10937 expand %{ 10938 iRegLdst src1s; 10939 iRegLdst src2s; 10940 iRegLdst diff; 10941 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10942 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10943 subL_reg_reg(diff, src1s, src2s); 10944 // Need to consider >=33 bit result, therefore we need signmaskL. 10945 signmask64I_regL(dst, diff); 10946 %} 10947 %} 10948 10949 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10950 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10951 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10952 size(4); 10953 ins_encode %{ 10954 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10955 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10956 %} 10957 ins_pipe(pipe_class_default); 10958 %} 10959 10960 //----------Arithmetic Conversion Instructions--------------------------------- 10961 10962 // Convert to Byte -- nop 10963 // Convert to Short -- nop 10964 10965 // Convert to Int 10966 10967 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10968 match(Set dst (RShiftI (LShiftI src amount) amount)); 10969 format %{ "EXTSB $dst, $src \t// byte->int" %} 10970 size(4); 10971 ins_encode %{ 10972 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10973 __ extsb($dst$$Register, $src$$Register); 10974 %} 10975 ins_pipe(pipe_class_default); 10976 %} 10977 10978 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10979 effect(DEF dst, USE src); 10980 10981 size(4); 10982 ins_encode %{ 10983 __ extsh($dst$$Register, $src$$Register); 10984 %} 10985 ins_pipe(pipe_class_default); 10986 %} 10987 10988 // LShiftI 16 + RShiftI 16 converts short to int. 10989 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10990 match(Set dst (RShiftI (LShiftI src amount) amount)); 10991 format %{ "EXTSH $dst, $src \t// short->int" %} 10992 size(4); 10993 ins_encode %{ 10994 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10995 __ extsh($dst$$Register, $src$$Register); 10996 %} 10997 ins_pipe(pipe_class_default); 10998 %} 10999 11000 // ConvL2I + ConvI2L: Sign extend int in long register. 11001 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11002 match(Set dst (ConvI2L (ConvL2I src))); 11003 11004 format %{ "EXTSW $dst, $src \t// long->long" %} 11005 size(4); 11006 ins_encode %{ 11007 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11008 __ extsw($dst$$Register, $src$$Register); 11009 %} 11010 ins_pipe(pipe_class_default); 11011 %} 11012 11013 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11014 match(Set dst (ConvL2I src)); 11015 format %{ "MR $dst, $src \t// long->int" %} 11016 // variable size, 0 or 4 11017 ins_encode %{ 11018 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11019 __ mr_if_needed($dst$$Register, $src$$Register); 11020 %} 11021 ins_pipe(pipe_class_default); 11022 %} 11023 11024 instruct convD2IRaw_regD(regD dst, regD src) %{ 11025 // no match-rule, false predicate 11026 effect(DEF dst, USE src); 11027 predicate(false); 11028 11029 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11030 size(4); 11031 ins_encode %{ 11032 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11033 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11034 %} 11035 ins_pipe(pipe_class_default); 11036 %} 11037 11038 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11039 // no match-rule, false predicate 11040 effect(DEF dst, USE crx, USE src); 11041 predicate(false); 11042 11043 ins_variable_size_depending_on_alignment(true); 11044 11045 format %{ "cmovI $crx, $dst, $src" %} 11046 // Worst case is branch + move + stop, no stop without scheduler. 11047 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11048 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11049 ins_pipe(pipe_class_default); 11050 %} 11051 11052 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11053 // no match-rule, false predicate 11054 effect(DEF dst, USE crx, USE src); 11055 predicate(false); 11056 11057 ins_variable_size_depending_on_alignment(true); 11058 11059 format %{ "cmovI $crx, $dst, $src" %} 11060 // Worst case is branch + move + stop, no stop without scheduler. 11061 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11062 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11063 ins_pipe(pipe_class_default); 11064 %} 11065 11066 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11067 // no match-rule, false predicate 11068 effect(DEF dst, USE crx, USE mem); 11069 predicate(false); 11070 11071 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11072 postalloc_expand %{ 11073 // 11074 // replaces 11075 // 11076 // region dst crx mem 11077 // \ | | / 11078 // dst=cmovI_bso_stackSlotL_conLvalue0 11079 // 11080 // with 11081 // 11082 // region dst 11083 // \ / 11084 // dst=loadConI16(0) 11085 // | 11086 // ^ region dst crx mem 11087 // | \ | | / 11088 // dst=cmovI_bso_stackSlotL 11089 // 11090 11091 // Create new nodes. 11092 MachNode *m1 = new loadConI16Node(); 11093 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11094 11095 // inputs for new nodes 11096 m1->add_req(n_region); 11097 m2->add_req(n_region, n_crx, n_mem); 11098 11099 // precedences for new nodes 11100 m2->add_prec(m1); 11101 11102 // operands for new nodes 11103 m1->_opnds[0] = op_dst; 11104 m1->_opnds[1] = new immI16Oper(0); 11105 11106 m2->_opnds[0] = op_dst; 11107 m2->_opnds[1] = op_crx; 11108 m2->_opnds[2] = op_mem; 11109 11110 // registers for new nodes 11111 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11112 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11113 11114 // Insert new nodes. 11115 nodes->push(m1); 11116 nodes->push(m2); 11117 %} 11118 %} 11119 11120 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11121 // no match-rule, false predicate 11122 effect(DEF dst, USE crx, USE src); 11123 predicate(false); 11124 11125 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11126 postalloc_expand %{ 11127 // 11128 // replaces 11129 // 11130 // region dst crx src 11131 // \ | | / 11132 // dst=cmovI_bso_reg_conLvalue0 11133 // 11134 // with 11135 // 11136 // region dst 11137 // \ / 11138 // dst=loadConI16(0) 11139 // | 11140 // ^ region dst crx src 11141 // | \ | | / 11142 // dst=cmovI_bso_reg 11143 // 11144 11145 // Create new nodes. 11146 MachNode *m1 = new loadConI16Node(); 11147 MachNode *m2 = new cmovI_bso_regNode(); 11148 11149 // inputs for new nodes 11150 m1->add_req(n_region); 11151 m2->add_req(n_region, n_crx, n_src); 11152 11153 // precedences for new nodes 11154 m2->add_prec(m1); 11155 11156 // operands for new nodes 11157 m1->_opnds[0] = op_dst; 11158 m1->_opnds[1] = new immI16Oper(0); 11159 11160 m2->_opnds[0] = op_dst; 11161 m2->_opnds[1] = op_crx; 11162 m2->_opnds[2] = op_src; 11163 11164 // registers for new nodes 11165 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11166 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11167 11168 // Insert new nodes. 11169 nodes->push(m1); 11170 nodes->push(m2); 11171 %} 11172 %} 11173 11174 // Double to Int conversion, NaN is mapped to 0. 11175 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11176 match(Set dst (ConvD2I src)); 11177 predicate(!VM_Version::has_mtfprd()); 11178 ins_cost(DEFAULT_COST); 11179 11180 expand %{ 11181 regD tmpD; 11182 stackSlotL tmpS; 11183 flagsReg crx; 11184 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11185 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11186 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11187 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11188 %} 11189 %} 11190 11191 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11192 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11193 match(Set dst (ConvD2I src)); 11194 predicate(VM_Version::has_mtfprd()); 11195 ins_cost(DEFAULT_COST); 11196 11197 expand %{ 11198 regD tmpD; 11199 flagsReg crx; 11200 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11201 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11202 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11203 %} 11204 %} 11205 11206 instruct convF2IRaw_regF(regF dst, regF src) %{ 11207 // no match-rule, false predicate 11208 effect(DEF dst, USE src); 11209 predicate(false); 11210 11211 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11212 size(4); 11213 ins_encode %{ 11214 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11215 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11216 %} 11217 ins_pipe(pipe_class_default); 11218 %} 11219 11220 // Float to Int conversion, NaN is mapped to 0. 11221 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11222 match(Set dst (ConvF2I src)); 11223 predicate(!VM_Version::has_mtfprd()); 11224 ins_cost(DEFAULT_COST); 11225 11226 expand %{ 11227 regF tmpF; 11228 stackSlotL tmpS; 11229 flagsReg crx; 11230 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11231 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11232 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11233 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11234 %} 11235 %} 11236 11237 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11238 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11239 match(Set dst (ConvF2I src)); 11240 predicate(VM_Version::has_mtfprd()); 11241 ins_cost(DEFAULT_COST); 11242 11243 expand %{ 11244 regF tmpF; 11245 flagsReg crx; 11246 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11247 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11248 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11249 %} 11250 %} 11251 11252 // Convert to Long 11253 11254 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11255 match(Set dst (ConvI2L src)); 11256 format %{ "EXTSW $dst, $src \t// int->long" %} 11257 size(4); 11258 ins_encode %{ 11259 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11260 __ extsw($dst$$Register, $src$$Register); 11261 %} 11262 ins_pipe(pipe_class_default); 11263 %} 11264 11265 // Zero-extend: convert unsigned int to long (convUI2L). 11266 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11267 match(Set dst (AndL (ConvI2L src) mask)); 11268 ins_cost(DEFAULT_COST); 11269 11270 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11271 size(4); 11272 ins_encode %{ 11273 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11274 __ clrldi($dst$$Register, $src$$Register, 32); 11275 %} 11276 ins_pipe(pipe_class_default); 11277 %} 11278 11279 // Zero-extend: convert unsigned int to long in long register. 11280 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11281 match(Set dst (AndL src mask)); 11282 ins_cost(DEFAULT_COST); 11283 11284 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11285 size(4); 11286 ins_encode %{ 11287 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11288 __ clrldi($dst$$Register, $src$$Register, 32); 11289 %} 11290 ins_pipe(pipe_class_default); 11291 %} 11292 11293 instruct convF2LRaw_regF(regF dst, regF src) %{ 11294 // no match-rule, false predicate 11295 effect(DEF dst, USE src); 11296 predicate(false); 11297 11298 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11299 size(4); 11300 ins_encode %{ 11301 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11302 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11303 %} 11304 ins_pipe(pipe_class_default); 11305 %} 11306 11307 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11308 // no match-rule, false predicate 11309 effect(DEF dst, USE crx, USE src); 11310 predicate(false); 11311 11312 ins_variable_size_depending_on_alignment(true); 11313 11314 format %{ "cmovL $crx, $dst, $src" %} 11315 // Worst case is branch + move + stop, no stop without scheduler. 11316 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11317 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11318 ins_pipe(pipe_class_default); 11319 %} 11320 11321 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11322 // no match-rule, false predicate 11323 effect(DEF dst, USE crx, USE src); 11324 predicate(false); 11325 11326 ins_variable_size_depending_on_alignment(true); 11327 11328 format %{ "cmovL $crx, $dst, $src" %} 11329 // Worst case is branch + move + stop, no stop without scheduler. 11330 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11331 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11332 ins_pipe(pipe_class_default); 11333 %} 11334 11335 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11336 // no match-rule, false predicate 11337 effect(DEF dst, USE crx, USE mem); 11338 predicate(false); 11339 11340 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11341 postalloc_expand %{ 11342 // 11343 // replaces 11344 // 11345 // region dst crx mem 11346 // \ | | / 11347 // dst=cmovL_bso_stackSlotL_conLvalue0 11348 // 11349 // with 11350 // 11351 // region dst 11352 // \ / 11353 // dst=loadConL16(0) 11354 // | 11355 // ^ region dst crx mem 11356 // | \ | | / 11357 // dst=cmovL_bso_stackSlotL 11358 // 11359 11360 // Create new nodes. 11361 MachNode *m1 = new loadConL16Node(); 11362 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11363 11364 // inputs for new nodes 11365 m1->add_req(n_region); 11366 m2->add_req(n_region, n_crx, n_mem); 11367 m2->add_prec(m1); 11368 11369 // operands for new nodes 11370 m1->_opnds[0] = op_dst; 11371 m1->_opnds[1] = new immL16Oper(0); 11372 m2->_opnds[0] = op_dst; 11373 m2->_opnds[1] = op_crx; 11374 m2->_opnds[2] = op_mem; 11375 11376 // registers for new nodes 11377 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11378 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11379 11380 // Insert new nodes. 11381 nodes->push(m1); 11382 nodes->push(m2); 11383 %} 11384 %} 11385 11386 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11387 // no match-rule, false predicate 11388 effect(DEF dst, USE crx, USE src); 11389 predicate(false); 11390 11391 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11392 postalloc_expand %{ 11393 // 11394 // replaces 11395 // 11396 // region dst crx src 11397 // \ | | / 11398 // dst=cmovL_bso_reg_conLvalue0 11399 // 11400 // with 11401 // 11402 // region dst 11403 // \ / 11404 // dst=loadConL16(0) 11405 // | 11406 // ^ region dst crx src 11407 // | \ | | / 11408 // dst=cmovL_bso_reg 11409 // 11410 11411 // Create new nodes. 11412 MachNode *m1 = new loadConL16Node(); 11413 MachNode *m2 = new cmovL_bso_regNode(); 11414 11415 // inputs for new nodes 11416 m1->add_req(n_region); 11417 m2->add_req(n_region, n_crx, n_src); 11418 m2->add_prec(m1); 11419 11420 // operands for new nodes 11421 m1->_opnds[0] = op_dst; 11422 m1->_opnds[1] = new immL16Oper(0); 11423 m2->_opnds[0] = op_dst; 11424 m2->_opnds[1] = op_crx; 11425 m2->_opnds[2] = op_src; 11426 11427 // registers for new nodes 11428 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11429 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11430 11431 // Insert new nodes. 11432 nodes->push(m1); 11433 nodes->push(m2); 11434 %} 11435 %} 11436 11437 // Float to Long conversion, NaN is mapped to 0. 11438 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11439 match(Set dst (ConvF2L src)); 11440 predicate(!VM_Version::has_mtfprd()); 11441 ins_cost(DEFAULT_COST); 11442 11443 expand %{ 11444 regF tmpF; 11445 stackSlotL tmpS; 11446 flagsReg crx; 11447 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11448 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11449 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11450 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11451 %} 11452 %} 11453 11454 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11455 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11456 match(Set dst (ConvF2L src)); 11457 predicate(VM_Version::has_mtfprd()); 11458 ins_cost(DEFAULT_COST); 11459 11460 expand %{ 11461 regF tmpF; 11462 flagsReg crx; 11463 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11464 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11465 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11466 %} 11467 %} 11468 11469 instruct convD2LRaw_regD(regD dst, regD src) %{ 11470 // no match-rule, false predicate 11471 effect(DEF dst, USE src); 11472 predicate(false); 11473 11474 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11475 size(4); 11476 ins_encode %{ 11477 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11478 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11479 %} 11480 ins_pipe(pipe_class_default); 11481 %} 11482 11483 // Double to Long conversion, NaN is mapped to 0. 11484 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11485 match(Set dst (ConvD2L src)); 11486 predicate(!VM_Version::has_mtfprd()); 11487 ins_cost(DEFAULT_COST); 11488 11489 expand %{ 11490 regD tmpD; 11491 stackSlotL tmpS; 11492 flagsReg crx; 11493 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11494 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11495 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11496 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11497 %} 11498 %} 11499 11500 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11501 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11502 match(Set dst (ConvD2L src)); 11503 predicate(VM_Version::has_mtfprd()); 11504 ins_cost(DEFAULT_COST); 11505 11506 expand %{ 11507 regD tmpD; 11508 flagsReg crx; 11509 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11510 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11511 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11512 %} 11513 %} 11514 11515 // Convert to Float 11516 11517 // Placed here as needed in expand. 11518 instruct convL2DRaw_regD(regD dst, regD src) %{ 11519 // no match-rule, false predicate 11520 effect(DEF dst, USE src); 11521 predicate(false); 11522 11523 format %{ "FCFID $dst, $src \t// convL2D" %} 11524 size(4); 11525 ins_encode %{ 11526 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11527 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11528 %} 11529 ins_pipe(pipe_class_default); 11530 %} 11531 11532 // Placed here as needed in expand. 11533 instruct convD2F_reg(regF dst, regD src) %{ 11534 match(Set dst (ConvD2F src)); 11535 format %{ "FRSP $dst, $src \t// convD2F" %} 11536 size(4); 11537 ins_encode %{ 11538 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11539 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11540 %} 11541 ins_pipe(pipe_class_default); 11542 %} 11543 11544 // Integer to Float conversion. 11545 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11546 match(Set dst (ConvI2F src)); 11547 predicate(!VM_Version::has_fcfids()); 11548 ins_cost(DEFAULT_COST); 11549 11550 expand %{ 11551 iRegLdst tmpL; 11552 stackSlotL tmpS; 11553 regD tmpD; 11554 regD tmpD2; 11555 convI2L_reg(tmpL, src); // Sign-extension int to long. 11556 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11557 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11558 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11559 convD2F_reg(dst, tmpD2); // Convert double to float. 11560 %} 11561 %} 11562 11563 instruct convL2FRaw_regF(regF dst, regD src) %{ 11564 // no match-rule, false predicate 11565 effect(DEF dst, USE src); 11566 predicate(false); 11567 11568 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11569 size(4); 11570 ins_encode %{ 11571 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11572 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11573 %} 11574 ins_pipe(pipe_class_default); 11575 %} 11576 11577 // Integer to Float conversion. Special version for Power7. 11578 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11579 match(Set dst (ConvI2F src)); 11580 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11581 ins_cost(DEFAULT_COST); 11582 11583 expand %{ 11584 iRegLdst tmpL; 11585 stackSlotL tmpS; 11586 regD tmpD; 11587 convI2L_reg(tmpL, src); // Sign-extension int to long. 11588 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11589 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11590 convL2FRaw_regF(dst, tmpD); // Convert to float. 11591 %} 11592 %} 11593 11594 // Integer to Float conversion. Special version for Power8. 11595 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11596 match(Set dst (ConvI2F src)); 11597 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11598 ins_cost(DEFAULT_COST); 11599 11600 expand %{ 11601 regD tmpD; 11602 moveI2D_reg(tmpD, src); 11603 convL2FRaw_regF(dst, tmpD); // Convert to float. 11604 %} 11605 %} 11606 11607 // L2F to avoid runtime call. 11608 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11609 match(Set dst (ConvL2F src)); 11610 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11611 ins_cost(DEFAULT_COST); 11612 11613 expand %{ 11614 stackSlotL tmpS; 11615 regD tmpD; 11616 regL_to_stkL(tmpS, src); // Store long to stack. 11617 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11618 convL2FRaw_regF(dst, tmpD); // Convert to float. 11619 %} 11620 %} 11621 11622 // L2F to avoid runtime call. Special version for Power8. 11623 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11624 match(Set dst (ConvL2F src)); 11625 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11626 ins_cost(DEFAULT_COST); 11627 11628 expand %{ 11629 regD tmpD; 11630 moveL2D_reg(tmpD, src); 11631 convL2FRaw_regF(dst, tmpD); // Convert to float. 11632 %} 11633 %} 11634 11635 // Moved up as used in expand. 11636 //instruct convD2F_reg(regF dst, regD src) %{%} 11637 11638 // Convert to Double 11639 11640 // Integer to Double conversion. 11641 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11642 match(Set dst (ConvI2D src)); 11643 predicate(!VM_Version::has_mtfprd()); 11644 ins_cost(DEFAULT_COST); 11645 11646 expand %{ 11647 iRegLdst tmpL; 11648 stackSlotL tmpS; 11649 regD tmpD; 11650 convI2L_reg(tmpL, src); // Sign-extension int to long. 11651 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11652 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11653 convL2DRaw_regD(dst, tmpD); // Convert to double. 11654 %} 11655 %} 11656 11657 // Integer to Double conversion. Special version for Power8. 11658 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11659 match(Set dst (ConvI2D src)); 11660 predicate(VM_Version::has_mtfprd()); 11661 ins_cost(DEFAULT_COST); 11662 11663 expand %{ 11664 regD tmpD; 11665 moveI2D_reg(tmpD, src); 11666 convL2DRaw_regD(dst, tmpD); // Convert to double. 11667 %} 11668 %} 11669 11670 // Long to Double conversion 11671 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11672 match(Set dst (ConvL2D src)); 11673 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11674 11675 expand %{ 11676 regD tmpD; 11677 moveL2D_stack_reg(tmpD, src); 11678 convL2DRaw_regD(dst, tmpD); 11679 %} 11680 %} 11681 11682 // Long to Double conversion. Special version for Power8. 11683 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11684 match(Set dst (ConvL2D src)); 11685 predicate(VM_Version::has_mtfprd()); 11686 ins_cost(DEFAULT_COST); 11687 11688 expand %{ 11689 regD tmpD; 11690 moveL2D_reg(tmpD, src); 11691 convL2DRaw_regD(dst, tmpD); // Convert to double. 11692 %} 11693 %} 11694 11695 instruct convF2D_reg(regD dst, regF src) %{ 11696 match(Set dst (ConvF2D src)); 11697 format %{ "FMR $dst, $src \t// float->double" %} 11698 // variable size, 0 or 4 11699 ins_encode %{ 11700 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11701 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11702 %} 11703 ins_pipe(pipe_class_default); 11704 %} 11705 11706 //----------Control Flow Instructions------------------------------------------ 11707 // Compare Instructions 11708 11709 // Compare Integers 11710 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11711 match(Set crx (CmpI src1 src2)); 11712 size(4); 11713 format %{ "CMPW $crx, $src1, $src2" %} 11714 ins_encode %{ 11715 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11716 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11717 %} 11718 ins_pipe(pipe_class_compare); 11719 %} 11720 11721 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11722 match(Set crx (CmpI src1 src2)); 11723 format %{ "CMPWI $crx, $src1, $src2" %} 11724 size(4); 11725 ins_encode %{ 11726 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11727 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11728 %} 11729 ins_pipe(pipe_class_compare); 11730 %} 11731 11732 // (src1 & src2) == 0? 11733 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11734 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11735 // r0 is killed 11736 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11737 size(4); 11738 ins_encode %{ 11739 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11740 __ andi_(R0, $src1$$Register, $src2$$constant); 11741 %} 11742 ins_pipe(pipe_class_compare); 11743 %} 11744 11745 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11746 match(Set crx (CmpL src1 src2)); 11747 format %{ "CMPD $crx, $src1, $src2" %} 11748 size(4); 11749 ins_encode %{ 11750 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11751 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11752 %} 11753 ins_pipe(pipe_class_compare); 11754 %} 11755 11756 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11757 match(Set crx (CmpL src1 src2)); 11758 format %{ "CMPDI $crx, $src1, $src2" %} 11759 size(4); 11760 ins_encode %{ 11761 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11762 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11763 %} 11764 ins_pipe(pipe_class_compare); 11765 %} 11766 11767 // Added CmpUL for LoopPredicate. 11768 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11769 match(Set crx (CmpUL src1 src2)); 11770 format %{ "CMPLD $crx, $src1, $src2" %} 11771 size(4); 11772 ins_encode %{ 11773 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11774 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11775 %} 11776 ins_pipe(pipe_class_compare); 11777 %} 11778 11779 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11780 match(Set crx (CmpUL src1 src2)); 11781 format %{ "CMPLDI $crx, $src1, $src2" %} 11782 size(4); 11783 ins_encode %{ 11784 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11785 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11786 %} 11787 ins_pipe(pipe_class_compare); 11788 %} 11789 11790 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11791 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11792 // r0 is killed 11793 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11794 size(4); 11795 ins_encode %{ 11796 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11797 __ and_(R0, $src1$$Register, $src2$$Register); 11798 %} 11799 ins_pipe(pipe_class_compare); 11800 %} 11801 11802 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11803 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11804 // r0 is killed 11805 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11806 size(4); 11807 ins_encode %{ 11808 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11809 __ andi_(R0, $src1$$Register, $src2$$constant); 11810 %} 11811 ins_pipe(pipe_class_compare); 11812 %} 11813 11814 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11815 // no match-rule, false predicate 11816 effect(DEF dst, USE crx); 11817 predicate(false); 11818 11819 ins_variable_size_depending_on_alignment(true); 11820 11821 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11822 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11823 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11824 ins_encode %{ 11825 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11826 Label done; 11827 // li(Rdst, 0); // equal -> 0 11828 __ beq($crx$$CondRegister, done); 11829 __ li($dst$$Register, 1); // greater -> +1 11830 __ bgt($crx$$CondRegister, done); 11831 __ li($dst$$Register, -1); // unordered or less -> -1 11832 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11833 __ bind(done); 11834 %} 11835 ins_pipe(pipe_class_compare); 11836 %} 11837 11838 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11839 // no match-rule, false predicate 11840 effect(DEF dst, USE crx); 11841 predicate(false); 11842 11843 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11844 postalloc_expand %{ 11845 // 11846 // replaces 11847 // 11848 // region crx 11849 // \ | 11850 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11851 // 11852 // with 11853 // 11854 // region 11855 // \ 11856 // dst=loadConI16(0) 11857 // | 11858 // ^ region crx 11859 // | \ | 11860 // dst=cmovI_conIvalueMinus1_conIvalue1 11861 // 11862 11863 // Create new nodes. 11864 MachNode *m1 = new loadConI16Node(); 11865 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11866 11867 // inputs for new nodes 11868 m1->add_req(n_region); 11869 m2->add_req(n_region, n_crx); 11870 m2->add_prec(m1); 11871 11872 // operands for new nodes 11873 m1->_opnds[0] = op_dst; 11874 m1->_opnds[1] = new immI16Oper(0); 11875 m2->_opnds[0] = op_dst; 11876 m2->_opnds[1] = op_crx; 11877 11878 // registers for new nodes 11879 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11880 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11881 11882 // Insert new nodes. 11883 nodes->push(m1); 11884 nodes->push(m2); 11885 %} 11886 %} 11887 11888 // Manifest a CmpL3 result in an integer register. Very painful. 11889 // This is the test to avoid. 11890 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11891 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11892 match(Set dst (CmpL3 src1 src2)); 11893 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11894 11895 expand %{ 11896 flagsReg tmp1; 11897 cmpL_reg_reg(tmp1, src1, src2); 11898 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11899 %} 11900 %} 11901 11902 // Implicit range checks. 11903 // A range check in the ideal world has one of the following shapes: 11904 // - (If le (CmpU length index)), (IfTrue throw exception) 11905 // - (If lt (CmpU index length)), (IfFalse throw exception) 11906 // 11907 // Match range check 'If le (CmpU length index)'. 11908 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11909 match(If cmp (CmpU src_length index)); 11910 effect(USE labl); 11911 predicate(TrapBasedRangeChecks && 11912 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11913 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11914 (Matcher::branches_to_uncommon_trap(_leaf))); 11915 11916 ins_is_TrapBasedCheckNode(true); 11917 11918 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11919 size(4); 11920 ins_encode %{ 11921 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11922 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11923 __ trap_range_check_le($src_length$$Register, $index$$constant); 11924 } else { 11925 // Both successors are uncommon traps, probability is 0. 11926 // Node got flipped during fixup flow. 11927 assert($cmp$$cmpcode == 0x9, "must be greater"); 11928 __ trap_range_check_g($src_length$$Register, $index$$constant); 11929 } 11930 %} 11931 ins_pipe(pipe_class_trap); 11932 %} 11933 11934 // Match range check 'If lt (CmpU index length)'. 11935 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11936 match(If cmp (CmpU src_index src_length)); 11937 effect(USE labl); 11938 predicate(TrapBasedRangeChecks && 11939 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11940 _leaf->as_If()->_prob >= PROB_ALWAYS && 11941 (Matcher::branches_to_uncommon_trap(_leaf))); 11942 11943 ins_is_TrapBasedCheckNode(true); 11944 11945 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11946 size(4); 11947 ins_encode %{ 11948 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11949 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11950 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11951 } else { 11952 // Both successors are uncommon traps, probability is 0. 11953 // Node got flipped during fixup flow. 11954 assert($cmp$$cmpcode == 0x8, "must be less"); 11955 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11956 } 11957 %} 11958 ins_pipe(pipe_class_trap); 11959 %} 11960 11961 // Match range check 'If lt (CmpU index length)'. 11962 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11963 match(If cmp (CmpU src_index length)); 11964 effect(USE labl); 11965 predicate(TrapBasedRangeChecks && 11966 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11967 _leaf->as_If()->_prob >= PROB_ALWAYS && 11968 (Matcher::branches_to_uncommon_trap(_leaf))); 11969 11970 ins_is_TrapBasedCheckNode(true); 11971 11972 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11973 size(4); 11974 ins_encode %{ 11975 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11976 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11977 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11978 } else { 11979 // Both successors are uncommon traps, probability is 0. 11980 // Node got flipped during fixup flow. 11981 assert($cmp$$cmpcode == 0x8, "must be less"); 11982 __ trap_range_check_l($src_index$$Register, $length$$constant); 11983 } 11984 %} 11985 ins_pipe(pipe_class_trap); 11986 %} 11987 11988 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11989 match(Set crx (CmpU src1 src2)); 11990 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11991 size(4); 11992 ins_encode %{ 11993 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11994 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11995 %} 11996 ins_pipe(pipe_class_compare); 11997 %} 11998 11999 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12000 match(Set crx (CmpU src1 src2)); 12001 size(4); 12002 format %{ "CMPLWI $crx, $src1, $src2" %} 12003 ins_encode %{ 12004 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12005 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12006 %} 12007 ins_pipe(pipe_class_compare); 12008 %} 12009 12010 // Implicit zero checks (more implicit null checks). 12011 // No constant pool entries required. 12012 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12013 match(If cmp (CmpN value zero)); 12014 effect(USE labl); 12015 predicate(TrapBasedNullChecks && 12016 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12017 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12018 Matcher::branches_to_uncommon_trap(_leaf)); 12019 ins_cost(1); 12020 12021 ins_is_TrapBasedCheckNode(true); 12022 12023 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12024 size(4); 12025 ins_encode %{ 12026 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12027 if ($cmp$$cmpcode == 0xA) { 12028 __ trap_null_check($value$$Register); 12029 } else { 12030 // Both successors are uncommon traps, probability is 0. 12031 // Node got flipped during fixup flow. 12032 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12033 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12034 } 12035 %} 12036 ins_pipe(pipe_class_trap); 12037 %} 12038 12039 // Compare narrow oops. 12040 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12041 match(Set crx (CmpN src1 src2)); 12042 12043 size(4); 12044 ins_cost(2); 12045 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12046 ins_encode %{ 12047 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12048 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12049 %} 12050 ins_pipe(pipe_class_compare); 12051 %} 12052 12053 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12054 match(Set crx (CmpN src1 src2)); 12055 // Make this more expensive than zeroCheckN_iReg_imm0. 12056 ins_cost(2); 12057 12058 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12059 size(4); 12060 ins_encode %{ 12061 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12062 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12063 %} 12064 ins_pipe(pipe_class_compare); 12065 %} 12066 12067 // Implicit zero checks (more implicit null checks). 12068 // No constant pool entries required. 12069 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12070 match(If cmp (CmpP value zero)); 12071 effect(USE labl); 12072 predicate(TrapBasedNullChecks && 12073 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12074 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12075 Matcher::branches_to_uncommon_trap(_leaf)); 12076 ins_cost(1); // Should not be cheaper than zeroCheckN. 12077 12078 ins_is_TrapBasedCheckNode(true); 12079 12080 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12081 size(4); 12082 ins_encode %{ 12083 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12084 if ($cmp$$cmpcode == 0xA) { 12085 __ trap_null_check($value$$Register); 12086 } else { 12087 // Both successors are uncommon traps, probability is 0. 12088 // Node got flipped during fixup flow. 12089 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12090 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12091 } 12092 %} 12093 ins_pipe(pipe_class_trap); 12094 %} 12095 12096 // Compare Pointers 12097 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12098 match(Set crx (CmpP src1 src2)); 12099 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12100 size(4); 12101 ins_encode %{ 12102 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12103 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12104 %} 12105 ins_pipe(pipe_class_compare); 12106 %} 12107 12108 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12109 match(Set crx (CmpP src1 src2)); 12110 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12111 size(4); 12112 ins_encode %{ 12113 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12114 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12115 %} 12116 ins_pipe(pipe_class_compare); 12117 %} 12118 12119 // Used in postalloc expand. 12120 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12121 // This match rule prevents reordering of node before a safepoint. 12122 // This only makes sense if this instructions is used exclusively 12123 // for the expansion of EncodeP! 12124 match(Set crx (CmpP src1 src2)); 12125 predicate(false); 12126 12127 format %{ "CMPDI $crx, $src1, $src2" %} 12128 size(4); 12129 ins_encode %{ 12130 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12131 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12132 %} 12133 ins_pipe(pipe_class_compare); 12134 %} 12135 12136 //----------Float Compares---------------------------------------------------- 12137 12138 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12139 // Needs matchrule, see cmpDUnordered. 12140 match(Set crx (CmpF src1 src2)); 12141 // no match-rule, false predicate 12142 predicate(false); 12143 12144 format %{ "cmpFUrd $crx, $src1, $src2" %} 12145 size(4); 12146 ins_encode %{ 12147 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12148 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12149 %} 12150 ins_pipe(pipe_class_default); 12151 %} 12152 12153 instruct cmov_bns_less(flagsReg crx) %{ 12154 // no match-rule, false predicate 12155 effect(DEF crx); 12156 predicate(false); 12157 12158 ins_variable_size_depending_on_alignment(true); 12159 12160 format %{ "cmov $crx" %} 12161 // Worst case is branch + move + stop, no stop without scheduler. 12162 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12163 ins_encode %{ 12164 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12165 Label done; 12166 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12167 __ li(R0, 0); 12168 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12169 // TODO PPC port __ endgroup_if_needed(_size == 16); 12170 __ bind(done); 12171 %} 12172 ins_pipe(pipe_class_default); 12173 %} 12174 12175 // Compare floating, generate condition code. 12176 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12177 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12178 // 12179 // The following code sequence occurs a lot in mpegaudio: 12180 // 12181 // block BXX: 12182 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12183 // cmpFUrd CCR6, F11, F9 12184 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12185 // cmov CCR6 12186 // 8: instruct branchConSched: 12187 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12188 match(Set crx (CmpF src1 src2)); 12189 ins_cost(DEFAULT_COST+BRANCH_COST); 12190 12191 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12192 postalloc_expand %{ 12193 // 12194 // replaces 12195 // 12196 // region src1 src2 12197 // \ | | 12198 // crx=cmpF_reg_reg 12199 // 12200 // with 12201 // 12202 // region src1 src2 12203 // \ | | 12204 // crx=cmpFUnordered_reg_reg 12205 // | 12206 // ^ region 12207 // | \ 12208 // crx=cmov_bns_less 12209 // 12210 12211 // Create new nodes. 12212 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12213 MachNode *m2 = new cmov_bns_lessNode(); 12214 12215 // inputs for new nodes 12216 m1->add_req(n_region, n_src1, n_src2); 12217 m2->add_req(n_region); 12218 m2->add_prec(m1); 12219 12220 // operands for new nodes 12221 m1->_opnds[0] = op_crx; 12222 m1->_opnds[1] = op_src1; 12223 m1->_opnds[2] = op_src2; 12224 m2->_opnds[0] = op_crx; 12225 12226 // registers for new nodes 12227 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12228 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12229 12230 // Insert new nodes. 12231 nodes->push(m1); 12232 nodes->push(m2); 12233 %} 12234 %} 12235 12236 // Compare float, generate -1,0,1 12237 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12238 match(Set dst (CmpF3 src1 src2)); 12239 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12240 12241 expand %{ 12242 flagsReg tmp1; 12243 cmpFUnordered_reg_reg(tmp1, src1, src2); 12244 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12245 %} 12246 %} 12247 12248 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12249 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12250 // node right before the conditional move using it. 12251 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12252 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12253 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12254 // conditional move was supposed to be spilled. 12255 match(Set crx (CmpD src1 src2)); 12256 // False predicate, shall not be matched. 12257 predicate(false); 12258 12259 format %{ "cmpFUrd $crx, $src1, $src2" %} 12260 size(4); 12261 ins_encode %{ 12262 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12263 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12264 %} 12265 ins_pipe(pipe_class_default); 12266 %} 12267 12268 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12269 match(Set crx (CmpD src1 src2)); 12270 ins_cost(DEFAULT_COST+BRANCH_COST); 12271 12272 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12273 postalloc_expand %{ 12274 // 12275 // replaces 12276 // 12277 // region src1 src2 12278 // \ | | 12279 // crx=cmpD_reg_reg 12280 // 12281 // with 12282 // 12283 // region src1 src2 12284 // \ | | 12285 // crx=cmpDUnordered_reg_reg 12286 // | 12287 // ^ region 12288 // | \ 12289 // crx=cmov_bns_less 12290 // 12291 12292 // create new nodes 12293 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12294 MachNode *m2 = new cmov_bns_lessNode(); 12295 12296 // inputs for new nodes 12297 m1->add_req(n_region, n_src1, n_src2); 12298 m2->add_req(n_region); 12299 m2->add_prec(m1); 12300 12301 // operands for new nodes 12302 m1->_opnds[0] = op_crx; 12303 m1->_opnds[1] = op_src1; 12304 m1->_opnds[2] = op_src2; 12305 m2->_opnds[0] = op_crx; 12306 12307 // registers for new nodes 12308 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12309 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12310 12311 // Insert new nodes. 12312 nodes->push(m1); 12313 nodes->push(m2); 12314 %} 12315 %} 12316 12317 // Compare double, generate -1,0,1 12318 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12319 match(Set dst (CmpD3 src1 src2)); 12320 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12321 12322 expand %{ 12323 flagsReg tmp1; 12324 cmpDUnordered_reg_reg(tmp1, src1, src2); 12325 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12326 %} 12327 %} 12328 12329 //----------Branches--------------------------------------------------------- 12330 // Jump 12331 12332 // Direct Branch. 12333 instruct branch(label labl) %{ 12334 match(Goto); 12335 effect(USE labl); 12336 ins_cost(BRANCH_COST); 12337 12338 format %{ "B $labl" %} 12339 size(4); 12340 ins_encode %{ 12341 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12342 Label d; // dummy 12343 __ bind(d); 12344 Label* p = $labl$$label; 12345 // `p' is `NULL' when this encoding class is used only to 12346 // determine the size of the encoded instruction. 12347 Label& l = (NULL == p)? d : *(p); 12348 __ b(l); 12349 %} 12350 ins_pipe(pipe_class_default); 12351 %} 12352 12353 // Conditional Near Branch 12354 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12355 // Same match rule as `branchConFar'. 12356 match(If cmp crx); 12357 effect(USE lbl); 12358 ins_cost(BRANCH_COST); 12359 12360 // If set to 1 this indicates that the current instruction is a 12361 // short variant of a long branch. This avoids using this 12362 // instruction in first-pass matching. It will then only be used in 12363 // the `Shorten_branches' pass. 12364 ins_short_branch(1); 12365 12366 format %{ "B$cmp $crx, $lbl" %} 12367 size(4); 12368 ins_encode( enc_bc(crx, cmp, lbl) ); 12369 ins_pipe(pipe_class_default); 12370 %} 12371 12372 // This is for cases when the ppc64 `bc' instruction does not 12373 // reach far enough. So we emit a far branch here, which is more 12374 // expensive. 12375 // 12376 // Conditional Far Branch 12377 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12378 // Same match rule as `branchCon'. 12379 match(If cmp crx); 12380 effect(USE crx, USE lbl); 12381 predicate(!false /* TODO: PPC port HB_Schedule*/); 12382 // Higher cost than `branchCon'. 12383 ins_cost(5*BRANCH_COST); 12384 12385 // This is not a short variant of a branch, but the long variant. 12386 ins_short_branch(0); 12387 12388 format %{ "B_FAR$cmp $crx, $lbl" %} 12389 size(8); 12390 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12391 ins_pipe(pipe_class_default); 12392 %} 12393 12394 // Conditional Branch used with Power6 scheduler (can be far or short). 12395 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12396 // Same match rule as `branchCon'. 12397 match(If cmp crx); 12398 effect(USE crx, USE lbl); 12399 predicate(false /* TODO: PPC port HB_Schedule*/); 12400 // Higher cost than `branchCon'. 12401 ins_cost(5*BRANCH_COST); 12402 12403 // Actually size doesn't depend on alignment but on shortening. 12404 ins_variable_size_depending_on_alignment(true); 12405 // long variant. 12406 ins_short_branch(0); 12407 12408 format %{ "B_FAR$cmp $crx, $lbl" %} 12409 size(8); // worst case 12410 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12411 ins_pipe(pipe_class_default); 12412 %} 12413 12414 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12415 match(CountedLoopEnd cmp crx); 12416 effect(USE labl); 12417 ins_cost(BRANCH_COST); 12418 12419 // short variant. 12420 ins_short_branch(1); 12421 12422 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12423 size(4); 12424 ins_encode( enc_bc(crx, cmp, labl) ); 12425 ins_pipe(pipe_class_default); 12426 %} 12427 12428 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12429 match(CountedLoopEnd cmp crx); 12430 effect(USE labl); 12431 predicate(!false /* TODO: PPC port HB_Schedule */); 12432 ins_cost(BRANCH_COST); 12433 12434 // Long variant. 12435 ins_short_branch(0); 12436 12437 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12438 size(8); 12439 ins_encode( enc_bc_far(crx, cmp, labl) ); 12440 ins_pipe(pipe_class_default); 12441 %} 12442 12443 // Conditional Branch used with Power6 scheduler (can be far or short). 12444 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12445 match(CountedLoopEnd cmp crx); 12446 effect(USE labl); 12447 predicate(false /* TODO: PPC port HB_Schedule */); 12448 // Higher cost than `branchCon'. 12449 ins_cost(5*BRANCH_COST); 12450 12451 // Actually size doesn't depend on alignment but on shortening. 12452 ins_variable_size_depending_on_alignment(true); 12453 // Long variant. 12454 ins_short_branch(0); 12455 12456 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12457 size(8); // worst case 12458 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12459 ins_pipe(pipe_class_default); 12460 %} 12461 12462 // ============================================================================ 12463 // Java runtime operations, intrinsics and other complex operations. 12464 12465 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12466 // array for an instance of the superklass. Set a hidden internal cache on a 12467 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12468 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12469 // 12470 // GL TODO: Improve this. 12471 // - result should not be a TEMP 12472 // - Add match rule as on sparc avoiding additional Cmp. 12473 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12474 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12475 match(Set result (PartialSubtypeCheck subklass superklass)); 12476 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12477 ins_cost(DEFAULT_COST*10); 12478 12479 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12480 ins_encode %{ 12481 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12482 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12483 $tmp_klass$$Register, NULL, $result$$Register); 12484 %} 12485 ins_pipe(pipe_class_default); 12486 %} 12487 12488 // inlined locking and unlocking 12489 12490 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12491 match(Set crx (FastLock oop box)); 12492 effect(TEMP tmp1, TEMP tmp2); 12493 predicate(!Compile::current()->use_rtm()); 12494 12495 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12496 ins_encode %{ 12497 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12498 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12499 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12500 UseBiasedLocking && !UseOptoBiasInlining); 12501 // If locking was successfull, crx should indicate 'EQ'. 12502 // The compiler generates a branch to the runtime call to 12503 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12504 %} 12505 ins_pipe(pipe_class_compare); 12506 %} 12507 12508 // Separate version for TM. Use bound register for box to enable USE_KILL. 12509 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12510 match(Set crx (FastLock oop box)); 12511 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12512 predicate(Compile::current()->use_rtm()); 12513 12514 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12515 ins_encode %{ 12516 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12517 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12518 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12519 /*Biased Locking*/ false, 12520 _rtm_counters, _stack_rtm_counters, 12521 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12522 /*TM*/ true, ra_->C->profile_rtm()); 12523 // If locking was successfull, crx should indicate 'EQ'. 12524 // The compiler generates a branch to the runtime call to 12525 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12526 %} 12527 ins_pipe(pipe_class_compare); 12528 %} 12529 12530 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12531 match(Set crx (FastUnlock oop box)); 12532 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12533 predicate(!Compile::current()->use_rtm()); 12534 12535 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12536 ins_encode %{ 12537 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12538 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12539 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12540 UseBiasedLocking && !UseOptoBiasInlining, 12541 false); 12542 // If unlocking was successfull, crx should indicate 'EQ'. 12543 // The compiler generates a branch to the runtime call to 12544 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12545 %} 12546 ins_pipe(pipe_class_compare); 12547 %} 12548 12549 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12550 match(Set crx (FastUnlock oop box)); 12551 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12552 predicate(Compile::current()->use_rtm()); 12553 12554 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12555 ins_encode %{ 12556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12557 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12558 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12559 /*Biased Locking*/ false, /*TM*/ true); 12560 // If unlocking was successfull, crx should indicate 'EQ'. 12561 // The compiler generates a branch to the runtime call to 12562 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12563 %} 12564 ins_pipe(pipe_class_compare); 12565 %} 12566 12567 // Align address. 12568 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12569 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12570 12571 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12572 size(4); 12573 ins_encode %{ 12574 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12575 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12576 %} 12577 ins_pipe(pipe_class_default); 12578 %} 12579 12580 // Array size computation. 12581 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12582 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12583 12584 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12585 size(4); 12586 ins_encode %{ 12587 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12588 __ subf($dst$$Register, $start$$Register, $end$$Register); 12589 %} 12590 ins_pipe(pipe_class_default); 12591 %} 12592 12593 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12594 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12595 match(Set dummy (ClearArray cnt base)); 12596 effect(USE_KILL base, KILL ctr); 12597 ins_cost(2 * MEMORY_REF_COST); 12598 12599 format %{ "ClearArray $cnt, $base" %} 12600 ins_encode %{ 12601 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12602 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12603 %} 12604 ins_pipe(pipe_class_default); 12605 %} 12606 12607 // Clear-array with constant large array length. 12608 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12609 match(Set dummy (ClearArray cnt base)); 12610 effect(USE_KILL base, TEMP tmp, KILL ctr); 12611 ins_cost(3 * MEMORY_REF_COST); 12612 12613 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12614 ins_encode %{ 12615 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12616 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12617 %} 12618 ins_pipe(pipe_class_default); 12619 %} 12620 12621 // Clear-array with dynamic array length. 12622 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12623 match(Set dummy (ClearArray cnt base)); 12624 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12625 ins_cost(4 * MEMORY_REF_COST); 12626 12627 format %{ "ClearArray $cnt, $base" %} 12628 ins_encode %{ 12629 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12630 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12631 %} 12632 ins_pipe(pipe_class_default); 12633 %} 12634 12635 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12636 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12637 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12638 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12639 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12640 ins_cost(300); 12641 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12642 ins_encode %{ 12643 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12644 __ string_compare($str1$$Register, $str2$$Register, 12645 $cnt1$$Register, $cnt2$$Register, 12646 $tmp$$Register, 12647 $result$$Register, StrIntrinsicNode::LL); 12648 %} 12649 ins_pipe(pipe_class_default); 12650 %} 12651 12652 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12653 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12654 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12655 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12656 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12657 ins_cost(300); 12658 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12659 ins_encode %{ 12660 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12661 __ string_compare($str1$$Register, $str2$$Register, 12662 $cnt1$$Register, $cnt2$$Register, 12663 $tmp$$Register, 12664 $result$$Register, StrIntrinsicNode::UU); 12665 %} 12666 ins_pipe(pipe_class_default); 12667 %} 12668 12669 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12670 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12671 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12672 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12673 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12674 ins_cost(300); 12675 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12676 ins_encode %{ 12677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12678 __ string_compare($str1$$Register, $str2$$Register, 12679 $cnt1$$Register, $cnt2$$Register, 12680 $tmp$$Register, 12681 $result$$Register, StrIntrinsicNode::LU); 12682 %} 12683 ins_pipe(pipe_class_default); 12684 %} 12685 12686 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12687 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12688 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12689 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12690 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12691 ins_cost(300); 12692 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12693 ins_encode %{ 12694 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12695 __ string_compare($str2$$Register, $str1$$Register, 12696 $cnt2$$Register, $cnt1$$Register, 12697 $tmp$$Register, 12698 $result$$Register, StrIntrinsicNode::UL); 12699 %} 12700 ins_pipe(pipe_class_default); 12701 %} 12702 12703 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12704 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12705 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12706 match(Set result (StrEquals (Binary str1 str2) cnt)); 12707 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12708 ins_cost(300); 12709 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12710 ins_encode %{ 12711 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12712 __ array_equals(false, $str1$$Register, $str2$$Register, 12713 $cnt$$Register, $tmp$$Register, 12714 $result$$Register, true /* byte */); 12715 %} 12716 ins_pipe(pipe_class_default); 12717 %} 12718 12719 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12720 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12721 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12722 match(Set result (StrEquals (Binary str1 str2) cnt)); 12723 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12724 ins_cost(300); 12725 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12726 ins_encode %{ 12727 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12728 __ array_equals(false, $str1$$Register, $str2$$Register, 12729 $cnt$$Register, $tmp$$Register, 12730 $result$$Register, false /* byte */); 12731 %} 12732 ins_pipe(pipe_class_default); 12733 %} 12734 12735 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12736 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12737 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12738 match(Set result (AryEq ary1 ary2)); 12739 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12740 ins_cost(300); 12741 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12742 ins_encode %{ 12743 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12744 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12745 $tmp1$$Register, $tmp2$$Register, 12746 $result$$Register, true /* byte */); 12747 %} 12748 ins_pipe(pipe_class_default); 12749 %} 12750 12751 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12752 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12753 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12754 match(Set result (AryEq ary1 ary2)); 12755 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12756 ins_cost(300); 12757 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12758 ins_encode %{ 12759 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12760 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12761 $tmp1$$Register, $tmp2$$Register, 12762 $result$$Register, false /* byte */); 12763 %} 12764 ins_pipe(pipe_class_default); 12765 %} 12766 12767 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12768 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12769 iRegIdst tmp1, iRegIdst tmp2, 12770 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12771 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12772 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12773 // Required for EA: check if it is still a type_array. 12774 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12775 ins_cost(150); 12776 12777 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12778 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12779 12780 ins_encode %{ 12781 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12782 immPOper *needleOper = (immPOper *)$needleImm; 12783 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12784 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12785 jchar chr; 12786 #ifdef VM_LITTLE_ENDIAN 12787 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12788 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12789 #else 12790 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12791 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12792 #endif 12793 __ string_indexof_char($result$$Register, 12794 $haystack$$Register, $haycnt$$Register, 12795 R0, chr, 12796 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12797 %} 12798 ins_pipe(pipe_class_compare); 12799 %} 12800 12801 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12802 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12803 iRegIdst tmp1, iRegIdst tmp2, 12804 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12805 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12806 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12807 // Required for EA: check if it is still a type_array. 12808 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12809 ins_cost(150); 12810 12811 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12812 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12813 12814 ins_encode %{ 12815 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12816 immPOper *needleOper = (immPOper *)$needleImm; 12817 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12818 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12819 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12820 __ string_indexof_char($result$$Register, 12821 $haystack$$Register, $haycnt$$Register, 12822 R0, chr, 12823 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12824 %} 12825 ins_pipe(pipe_class_compare); 12826 %} 12827 12828 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12829 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12830 iRegIdst tmp1, iRegIdst tmp2, 12831 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12832 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12833 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12834 // Required for EA: check if it is still a type_array. 12835 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12836 ins_cost(150); 12837 12838 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12839 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12840 12841 ins_encode %{ 12842 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12843 immPOper *needleOper = (immPOper *)$needleImm; 12844 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12845 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12846 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12847 __ string_indexof_char($result$$Register, 12848 $haystack$$Register, $haycnt$$Register, 12849 R0, chr, 12850 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12851 %} 12852 ins_pipe(pipe_class_compare); 12853 %} 12854 12855 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12856 rscratch2RegP needle, immI_1 needlecntImm, 12857 iRegIdst tmp1, iRegIdst tmp2, 12858 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12859 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12860 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12861 // Required for EA: check if it is still a type_array. 12862 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12863 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12864 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12865 ins_cost(180); 12866 12867 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12868 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12869 ins_encode %{ 12870 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12871 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12872 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12873 guarantee(needle_values, "sanity"); 12874 jchar chr; 12875 #ifdef VM_LITTLE_ENDIAN 12876 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12877 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12878 #else 12879 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12880 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12881 #endif 12882 __ string_indexof_char($result$$Register, 12883 $haystack$$Register, $haycnt$$Register, 12884 R0, chr, 12885 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12886 %} 12887 ins_pipe(pipe_class_compare); 12888 %} 12889 12890 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12891 rscratch2RegP needle, immI_1 needlecntImm, 12892 iRegIdst tmp1, iRegIdst tmp2, 12893 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12894 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12895 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12896 // Required for EA: check if it is still a type_array. 12897 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12898 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12899 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12900 ins_cost(180); 12901 12902 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12903 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12904 ins_encode %{ 12905 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12906 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12907 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12908 guarantee(needle_values, "sanity"); 12909 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12910 __ string_indexof_char($result$$Register, 12911 $haystack$$Register, $haycnt$$Register, 12912 R0, chr, 12913 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12914 %} 12915 ins_pipe(pipe_class_compare); 12916 %} 12917 12918 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12919 rscratch2RegP needle, immI_1 needlecntImm, 12920 iRegIdst tmp1, iRegIdst tmp2, 12921 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12922 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12923 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12924 // Required for EA: check if it is still a type_array. 12925 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12926 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12927 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12928 ins_cost(180); 12929 12930 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12931 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12932 ins_encode %{ 12933 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12934 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12935 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12936 guarantee(needle_values, "sanity"); 12937 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12938 __ string_indexof_char($result$$Register, 12939 $haystack$$Register, $haycnt$$Register, 12940 R0, chr, 12941 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12942 %} 12943 ins_pipe(pipe_class_compare); 12944 %} 12945 12946 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12947 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12948 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12949 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12950 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12951 ins_cost(180); 12952 12953 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12954 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12955 ins_encode %{ 12956 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12957 __ string_indexof_char($result$$Register, 12958 $haystack$$Register, $haycnt$$Register, 12959 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12960 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12961 %} 12962 ins_pipe(pipe_class_compare); 12963 %} 12964 12965 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12966 iRegPsrc needle, uimmI15 needlecntImm, 12967 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12968 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12969 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12970 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12971 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12972 // Required for EA: check if it is still a type_array. 12973 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12974 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12975 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12976 ins_cost(250); 12977 12978 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12979 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12980 ins_encode %{ 12981 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12982 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12983 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12984 12985 __ string_indexof($result$$Register, 12986 $haystack$$Register, $haycnt$$Register, 12987 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12988 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12989 %} 12990 ins_pipe(pipe_class_compare); 12991 %} 12992 12993 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12994 iRegPsrc needle, uimmI15 needlecntImm, 12995 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12996 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12997 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12998 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12999 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13000 // Required for EA: check if it is still a type_array. 13001 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13002 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13003 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13004 ins_cost(250); 13005 13006 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13007 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13008 ins_encode %{ 13009 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13010 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13011 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13012 13013 __ string_indexof($result$$Register, 13014 $haystack$$Register, $haycnt$$Register, 13015 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13016 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13017 %} 13018 ins_pipe(pipe_class_compare); 13019 %} 13020 13021 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13022 iRegPsrc needle, uimmI15 needlecntImm, 13023 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13024 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13025 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13026 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13027 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13028 // Required for EA: check if it is still a type_array. 13029 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13030 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13031 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13032 ins_cost(250); 13033 13034 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13035 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13036 ins_encode %{ 13037 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13038 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13039 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13040 13041 __ string_indexof($result$$Register, 13042 $haystack$$Register, $haycnt$$Register, 13043 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13044 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13045 %} 13046 ins_pipe(pipe_class_compare); 13047 %} 13048 13049 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13050 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13051 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13052 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13053 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13054 TEMP_DEF result, 13055 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13056 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13057 ins_cost(300); 13058 13059 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13060 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13061 ins_encode %{ 13062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13063 __ string_indexof($result$$Register, 13064 $haystack$$Register, $haycnt$$Register, 13065 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13066 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13067 %} 13068 ins_pipe(pipe_class_compare); 13069 %} 13070 13071 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13072 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13073 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13074 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13075 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13076 TEMP_DEF result, 13077 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13078 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13079 ins_cost(300); 13080 13081 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13082 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13083 ins_encode %{ 13084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13085 __ string_indexof($result$$Register, 13086 $haystack$$Register, $haycnt$$Register, 13087 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13088 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13089 %} 13090 ins_pipe(pipe_class_compare); 13091 %} 13092 13093 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13094 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13095 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13096 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13097 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13098 TEMP_DEF result, 13099 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13100 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13101 ins_cost(300); 13102 13103 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13104 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13105 ins_encode %{ 13106 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13107 __ string_indexof($result$$Register, 13108 $haystack$$Register, $haycnt$$Register, 13109 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13110 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13111 %} 13112 ins_pipe(pipe_class_compare); 13113 %} 13114 13115 // char[] to byte[] compression 13116 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13117 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13118 match(Set result (StrCompressedCopy src (Binary dst len))); 13119 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13120 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13121 ins_cost(300); 13122 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13123 ins_encode %{ 13124 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13125 Label Lskip, Ldone; 13126 __ li($result$$Register, 0); 13127 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13128 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13129 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13130 __ beq(CCR0, Lskip); 13131 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13132 __ bind(Lskip); 13133 __ mr($result$$Register, $len$$Register); 13134 __ bind(Ldone); 13135 %} 13136 ins_pipe(pipe_class_default); 13137 %} 13138 13139 // byte[] to char[] inflation 13140 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13141 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13142 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13143 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13144 ins_cost(300); 13145 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13146 ins_encode %{ 13147 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13148 Label Ldone; 13149 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13150 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13151 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13152 __ beq(CCR0, Ldone); 13153 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13154 __ bind(Ldone); 13155 %} 13156 ins_pipe(pipe_class_default); 13157 %} 13158 13159 // StringCoding.java intrinsics 13160 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13161 regCTR ctr, flagsRegCR0 cr0) 13162 %{ 13163 match(Set result (HasNegatives ary1 len)); 13164 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13165 ins_cost(300); 13166 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13167 ins_encode %{ 13168 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13169 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13170 $tmp1$$Register, $tmp2$$Register); 13171 %} 13172 ins_pipe(pipe_class_default); 13173 %} 13174 13175 // encode char[] to byte[] in ISO_8859_1 13176 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13177 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13178 match(Set result (EncodeISOArray src (Binary dst len))); 13179 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13180 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13181 ins_cost(300); 13182 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13183 ins_encode %{ 13184 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13185 Label Lslow, Lfailure1, Lfailure2, Ldone; 13186 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13187 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13188 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13189 __ beq(CCR0, Ldone); 13190 __ bind(Lslow); 13191 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13192 __ li($result$$Register, 0); 13193 __ b(Ldone); 13194 13195 __ bind(Lfailure1); 13196 __ mr($result$$Register, $len$$Register); 13197 __ mfctr($tmp1$$Register); 13198 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13199 __ beq(CCR0, Ldone); 13200 __ b(Lslow); 13201 13202 __ bind(Lfailure2); 13203 __ mfctr($result$$Register); // Remaining characters. 13204 13205 __ bind(Ldone); 13206 __ subf($result$$Register, $result$$Register, $len$$Register); 13207 %} 13208 ins_pipe(pipe_class_default); 13209 %} 13210 13211 13212 //---------- Min/Max Instructions --------------------------------------------- 13213 13214 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13215 match(Set dst (MinI src1 src2)); 13216 ins_cost(DEFAULT_COST*6); 13217 13218 expand %{ 13219 iRegLdst src1s; 13220 iRegLdst src2s; 13221 iRegLdst diff; 13222 iRegLdst sm; 13223 iRegLdst doz; // difference or zero 13224 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13225 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13226 subL_reg_reg(diff, src2s, src1s); 13227 // Need to consider >=33 bit result, therefore we need signmaskL. 13228 signmask64L_regL(sm, diff); 13229 andL_reg_reg(doz, diff, sm); // <=0 13230 addI_regL_regL(dst, doz, src1s); 13231 %} 13232 %} 13233 13234 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13235 match(Set dst (MinI src1 src2)); 13236 effect(KILL cr0); 13237 predicate(VM_Version::has_isel()); 13238 ins_cost(DEFAULT_COST*2); 13239 13240 ins_encode %{ 13241 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13242 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13243 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13244 %} 13245 ins_pipe(pipe_class_default); 13246 %} 13247 13248 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13249 match(Set dst (MaxI src1 src2)); 13250 ins_cost(DEFAULT_COST*6); 13251 13252 expand %{ 13253 iRegLdst src1s; 13254 iRegLdst src2s; 13255 iRegLdst diff; 13256 iRegLdst sm; 13257 iRegLdst doz; // difference or zero 13258 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13259 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13260 subL_reg_reg(diff, src2s, src1s); 13261 // Need to consider >=33 bit result, therefore we need signmaskL. 13262 signmask64L_regL(sm, diff); 13263 andcL_reg_reg(doz, diff, sm); // >=0 13264 addI_regL_regL(dst, doz, src1s); 13265 %} 13266 %} 13267 13268 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13269 match(Set dst (MaxI src1 src2)); 13270 effect(KILL cr0); 13271 predicate(VM_Version::has_isel()); 13272 ins_cost(DEFAULT_COST*2); 13273 13274 ins_encode %{ 13275 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13276 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13277 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13278 %} 13279 ins_pipe(pipe_class_default); 13280 %} 13281 13282 //---------- Population Count Instructions ------------------------------------ 13283 13284 // Popcnt for Power7. 13285 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13286 match(Set dst (PopCountI src)); 13287 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13288 ins_cost(DEFAULT_COST); 13289 13290 format %{ "POPCNTW $dst, $src" %} 13291 size(4); 13292 ins_encode %{ 13293 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13294 __ popcntw($dst$$Register, $src$$Register); 13295 %} 13296 ins_pipe(pipe_class_default); 13297 %} 13298 13299 // Popcnt for Power7. 13300 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13301 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13302 match(Set dst (PopCountL src)); 13303 ins_cost(DEFAULT_COST); 13304 13305 format %{ "POPCNTD $dst, $src" %} 13306 size(4); 13307 ins_encode %{ 13308 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13309 __ popcntd($dst$$Register, $src$$Register); 13310 %} 13311 ins_pipe(pipe_class_default); 13312 %} 13313 13314 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13315 match(Set dst (CountLeadingZerosI src)); 13316 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13317 ins_cost(DEFAULT_COST); 13318 13319 format %{ "CNTLZW $dst, $src" %} 13320 size(4); 13321 ins_encode %{ 13322 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13323 __ cntlzw($dst$$Register, $src$$Register); 13324 %} 13325 ins_pipe(pipe_class_default); 13326 %} 13327 13328 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13329 match(Set dst (CountLeadingZerosL src)); 13330 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13331 ins_cost(DEFAULT_COST); 13332 13333 format %{ "CNTLZD $dst, $src" %} 13334 size(4); 13335 ins_encode %{ 13336 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13337 __ cntlzd($dst$$Register, $src$$Register); 13338 %} 13339 ins_pipe(pipe_class_default); 13340 %} 13341 13342 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13343 // no match-rule, false predicate 13344 effect(DEF dst, USE src); 13345 predicate(false); 13346 13347 format %{ "CNTLZD $dst, $src" %} 13348 size(4); 13349 ins_encode %{ 13350 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13351 __ cntlzd($dst$$Register, $src$$Register); 13352 %} 13353 ins_pipe(pipe_class_default); 13354 %} 13355 13356 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13357 match(Set dst (CountTrailingZerosI src)); 13358 predicate(UseCountLeadingZerosInstructionsPPC64); 13359 ins_cost(DEFAULT_COST); 13360 13361 expand %{ 13362 immI16 imm1 %{ (int)-1 %} 13363 immI16 imm2 %{ (int)32 %} 13364 immI_minus1 m1 %{ -1 %} 13365 iRegIdst tmpI1; 13366 iRegIdst tmpI2; 13367 iRegIdst tmpI3; 13368 addI_reg_imm16(tmpI1, src, imm1); 13369 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13370 countLeadingZerosI(tmpI3, tmpI2); 13371 subI_imm16_reg(dst, imm2, tmpI3); 13372 %} 13373 %} 13374 13375 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13376 match(Set dst (CountTrailingZerosL src)); 13377 predicate(UseCountLeadingZerosInstructionsPPC64); 13378 ins_cost(DEFAULT_COST); 13379 13380 expand %{ 13381 immL16 imm1 %{ (long)-1 %} 13382 immI16 imm2 %{ (int)64 %} 13383 iRegLdst tmpL1; 13384 iRegLdst tmpL2; 13385 iRegIdst tmpL3; 13386 addL_reg_imm16(tmpL1, src, imm1); 13387 andcL_reg_reg(tmpL2, tmpL1, src); 13388 countLeadingZerosL(tmpL3, tmpL2); 13389 subI_imm16_reg(dst, imm2, tmpL3); 13390 %} 13391 %} 13392 13393 // Expand nodes for byte_reverse_int. 13394 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13395 effect(DEF dst, USE src, USE pos, USE shift); 13396 predicate(false); 13397 13398 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13399 size(4); 13400 ins_encode %{ 13401 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13402 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13403 %} 13404 ins_pipe(pipe_class_default); 13405 %} 13406 13407 // As insrwi_a, but with USE_DEF. 13408 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13409 effect(USE_DEF dst, USE src, USE pos, USE shift); 13410 predicate(false); 13411 13412 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13413 size(4); 13414 ins_encode %{ 13415 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13416 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13417 %} 13418 ins_pipe(pipe_class_default); 13419 %} 13420 13421 // Just slightly faster than java implementation. 13422 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13423 match(Set dst (ReverseBytesI src)); 13424 ins_cost(7*DEFAULT_COST); 13425 13426 expand %{ 13427 immI16 imm24 %{ (int) 24 %} 13428 immI16 imm16 %{ (int) 16 %} 13429 immI16 imm8 %{ (int) 8 %} 13430 immI16 imm4 %{ (int) 4 %} 13431 immI16 imm0 %{ (int) 0 %} 13432 iRegLdst tmpI1; 13433 iRegLdst tmpI2; 13434 iRegLdst tmpI3; 13435 13436 urShiftI_reg_imm(tmpI1, src, imm24); 13437 insrwi_a(dst, tmpI1, imm24, imm8); 13438 urShiftI_reg_imm(tmpI2, src, imm16); 13439 insrwi(dst, tmpI2, imm8, imm16); 13440 urShiftI_reg_imm(tmpI3, src, imm8); 13441 insrwi(dst, tmpI3, imm8, imm8); 13442 insrwi(dst, src, imm0, imm8); 13443 %} 13444 %} 13445 13446 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13447 match(Set dst (ReverseBytesL src)); 13448 ins_cost(15*DEFAULT_COST); 13449 13450 expand %{ 13451 immI16 imm56 %{ (int) 56 %} 13452 immI16 imm48 %{ (int) 48 %} 13453 immI16 imm40 %{ (int) 40 %} 13454 immI16 imm32 %{ (int) 32 %} 13455 immI16 imm24 %{ (int) 24 %} 13456 immI16 imm16 %{ (int) 16 %} 13457 immI16 imm8 %{ (int) 8 %} 13458 immI16 imm0 %{ (int) 0 %} 13459 iRegLdst tmpL1; 13460 iRegLdst tmpL2; 13461 iRegLdst tmpL3; 13462 iRegLdst tmpL4; 13463 iRegLdst tmpL5; 13464 iRegLdst tmpL6; 13465 13466 // src : |a|b|c|d|e|f|g|h| 13467 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13468 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13469 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13470 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13471 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13472 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13473 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13474 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13475 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13476 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13477 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13478 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13479 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13480 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13481 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13482 %} 13483 %} 13484 13485 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13486 match(Set dst (ReverseBytesUS src)); 13487 ins_cost(2*DEFAULT_COST); 13488 13489 expand %{ 13490 immI16 imm16 %{ (int) 16 %} 13491 immI16 imm8 %{ (int) 8 %} 13492 13493 urShiftI_reg_imm(dst, src, imm8); 13494 insrwi(dst, src, imm16, imm8); 13495 %} 13496 %} 13497 13498 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13499 match(Set dst (ReverseBytesS src)); 13500 ins_cost(3*DEFAULT_COST); 13501 13502 expand %{ 13503 immI16 imm16 %{ (int) 16 %} 13504 immI16 imm8 %{ (int) 8 %} 13505 iRegLdst tmpI1; 13506 13507 urShiftI_reg_imm(tmpI1, src, imm8); 13508 insrwi(tmpI1, src, imm16, imm8); 13509 extsh(dst, tmpI1); 13510 %} 13511 %} 13512 13513 // Load Integer reversed byte order 13514 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13515 match(Set dst (ReverseBytesI (LoadI mem))); 13516 ins_cost(MEMORY_REF_COST); 13517 13518 size(4); 13519 ins_encode %{ 13520 __ lwbrx($dst$$Register, $mem$$Register); 13521 %} 13522 ins_pipe(pipe_class_default); 13523 %} 13524 13525 // Load Long - aligned and reversed 13526 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13527 match(Set dst (ReverseBytesL (LoadL mem))); 13528 predicate(VM_Version::has_ldbrx()); 13529 ins_cost(MEMORY_REF_COST); 13530 13531 size(4); 13532 ins_encode %{ 13533 __ ldbrx($dst$$Register, $mem$$Register); 13534 %} 13535 ins_pipe(pipe_class_default); 13536 %} 13537 13538 // Load unsigned short / char reversed byte order 13539 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13540 match(Set dst (ReverseBytesUS (LoadUS mem))); 13541 ins_cost(MEMORY_REF_COST); 13542 13543 size(4); 13544 ins_encode %{ 13545 __ lhbrx($dst$$Register, $mem$$Register); 13546 %} 13547 ins_pipe(pipe_class_default); 13548 %} 13549 13550 // Load short reversed byte order 13551 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13552 match(Set dst (ReverseBytesS (LoadS mem))); 13553 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13554 13555 size(8); 13556 ins_encode %{ 13557 __ lhbrx($dst$$Register, $mem$$Register); 13558 __ extsh($dst$$Register, $dst$$Register); 13559 %} 13560 ins_pipe(pipe_class_default); 13561 %} 13562 13563 // Store Integer reversed byte order 13564 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13565 match(Set mem (StoreI mem (ReverseBytesI src))); 13566 ins_cost(MEMORY_REF_COST); 13567 13568 size(4); 13569 ins_encode %{ 13570 __ stwbrx($src$$Register, $mem$$Register); 13571 %} 13572 ins_pipe(pipe_class_default); 13573 %} 13574 13575 // Store Long reversed byte order 13576 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13577 match(Set mem (StoreL mem (ReverseBytesL src))); 13578 predicate(VM_Version::has_stdbrx()); 13579 ins_cost(MEMORY_REF_COST); 13580 13581 size(4); 13582 ins_encode %{ 13583 __ stdbrx($src$$Register, $mem$$Register); 13584 %} 13585 ins_pipe(pipe_class_default); 13586 %} 13587 13588 // Store unsigned short / char reversed byte order 13589 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13590 match(Set mem (StoreC mem (ReverseBytesUS src))); 13591 ins_cost(MEMORY_REF_COST); 13592 13593 size(4); 13594 ins_encode %{ 13595 __ sthbrx($src$$Register, $mem$$Register); 13596 %} 13597 ins_pipe(pipe_class_default); 13598 %} 13599 13600 // Store short reversed byte order 13601 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13602 match(Set mem (StoreC mem (ReverseBytesS src))); 13603 ins_cost(MEMORY_REF_COST); 13604 13605 size(4); 13606 ins_encode %{ 13607 __ sthbrx($src$$Register, $mem$$Register); 13608 %} 13609 ins_pipe(pipe_class_default); 13610 %} 13611 13612 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13613 effect(DEF temp1, USE src); 13614 13615 size(4); 13616 ins_encode %{ 13617 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13618 %} 13619 ins_pipe(pipe_class_default); 13620 %} 13621 13622 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13623 effect(DEF dst, USE src, USE imm1); 13624 13625 size(4); 13626 ins_encode %{ 13627 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13628 %} 13629 ins_pipe(pipe_class_default); 13630 %} 13631 13632 //---------- Replicate Vector Instructions ------------------------------------ 13633 13634 // Insrdi does replicate if src == dst. 13635 instruct repl32(iRegLdst dst) %{ 13636 predicate(false); 13637 effect(USE_DEF dst); 13638 13639 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13640 size(4); 13641 ins_encode %{ 13642 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13643 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13644 %} 13645 ins_pipe(pipe_class_default); 13646 %} 13647 13648 // Insrdi does replicate if src == dst. 13649 instruct repl48(iRegLdst dst) %{ 13650 predicate(false); 13651 effect(USE_DEF dst); 13652 13653 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13654 size(4); 13655 ins_encode %{ 13656 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13657 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13658 %} 13659 ins_pipe(pipe_class_default); 13660 %} 13661 13662 // Insrdi does replicate if src == dst. 13663 instruct repl56(iRegLdst dst) %{ 13664 predicate(false); 13665 effect(USE_DEF dst); 13666 13667 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13668 size(4); 13669 ins_encode %{ 13670 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13671 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13672 %} 13673 ins_pipe(pipe_class_default); 13674 %} 13675 13676 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13677 match(Set dst (ReplicateB src)); 13678 predicate(n->as_Vector()->length() == 8); 13679 expand %{ 13680 moveReg(dst, src); 13681 repl56(dst); 13682 repl48(dst); 13683 repl32(dst); 13684 %} 13685 %} 13686 13687 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13688 match(Set dst (ReplicateB zero)); 13689 predicate(n->as_Vector()->length() == 8); 13690 format %{ "LI $dst, #0 \t// replicate8B" %} 13691 size(4); 13692 ins_encode %{ 13693 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13694 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13695 %} 13696 ins_pipe(pipe_class_default); 13697 %} 13698 13699 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13700 match(Set dst (ReplicateB src)); 13701 predicate(n->as_Vector()->length() == 8); 13702 format %{ "LI $dst, #-1 \t// replicate8B" %} 13703 size(4); 13704 ins_encode %{ 13705 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13706 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13707 %} 13708 ins_pipe(pipe_class_default); 13709 %} 13710 13711 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13712 match(Set dst (ReplicateB src)); 13713 predicate(n->as_Vector()->length() == 16); 13714 13715 expand %{ 13716 iRegLdst tmpL; 13717 vecX tmpV; 13718 immI8 imm1 %{ (int) 1 %} 13719 moveReg(tmpL, src); 13720 repl56(tmpL); 13721 repl48(tmpL); 13722 mtvsrwz(tmpV, tmpL); 13723 xxspltw(dst, tmpV, imm1); 13724 %} 13725 %} 13726 13727 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13728 match(Set dst (ReplicateB zero)); 13729 predicate(n->as_Vector()->length() == 16); 13730 13731 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13732 size(4); 13733 ins_encode %{ 13734 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13735 %} 13736 ins_pipe(pipe_class_default); 13737 %} 13738 13739 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13740 match(Set dst (ReplicateB src)); 13741 predicate(n->as_Vector()->length() == 16); 13742 13743 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13744 size(4); 13745 ins_encode %{ 13746 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13747 %} 13748 ins_pipe(pipe_class_default); 13749 %} 13750 13751 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13752 match(Set dst (ReplicateS src)); 13753 predicate(n->as_Vector()->length() == 4); 13754 expand %{ 13755 moveReg(dst, src); 13756 repl48(dst); 13757 repl32(dst); 13758 %} 13759 %} 13760 13761 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13762 match(Set dst (ReplicateS zero)); 13763 predicate(n->as_Vector()->length() == 4); 13764 format %{ "LI $dst, #0 \t// replicate4C" %} 13765 size(4); 13766 ins_encode %{ 13767 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13768 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13769 %} 13770 ins_pipe(pipe_class_default); 13771 %} 13772 13773 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13774 match(Set dst (ReplicateS src)); 13775 predicate(n->as_Vector()->length() == 4); 13776 format %{ "LI $dst, -1 \t// replicate4C" %} 13777 size(4); 13778 ins_encode %{ 13779 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13780 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13781 %} 13782 ins_pipe(pipe_class_default); 13783 %} 13784 13785 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13786 match(Set dst (ReplicateS src)); 13787 predicate(n->as_Vector()->length() == 8); 13788 13789 expand %{ 13790 iRegLdst tmpL; 13791 vecX tmpV; 13792 immI8 zero %{ (int) 0 %} 13793 moveReg(tmpL, src); 13794 repl48(tmpL); 13795 repl32(tmpL); 13796 mtvsrd(tmpV, tmpL); 13797 xxpermdi(dst, tmpV, tmpV, zero); 13798 %} 13799 %} 13800 13801 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13802 match(Set dst (ReplicateS zero)); 13803 predicate(n->as_Vector()->length() == 8); 13804 13805 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13806 size(4); 13807 ins_encode %{ 13808 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13809 %} 13810 ins_pipe(pipe_class_default); 13811 %} 13812 13813 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13814 match(Set dst (ReplicateS src)); 13815 predicate(n->as_Vector()->length() == 8); 13816 13817 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13818 size(4); 13819 ins_encode %{ 13820 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13821 %} 13822 ins_pipe(pipe_class_default); 13823 %} 13824 13825 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13826 match(Set dst (ReplicateI src)); 13827 predicate(n->as_Vector()->length() == 2); 13828 ins_cost(2 * DEFAULT_COST); 13829 expand %{ 13830 moveReg(dst, src); 13831 repl32(dst); 13832 %} 13833 %} 13834 13835 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13836 match(Set dst (ReplicateI zero)); 13837 predicate(n->as_Vector()->length() == 2); 13838 format %{ "LI $dst, #0 \t// replicate4C" %} 13839 size(4); 13840 ins_encode %{ 13841 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13842 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13843 %} 13844 ins_pipe(pipe_class_default); 13845 %} 13846 13847 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13848 match(Set dst (ReplicateI src)); 13849 predicate(n->as_Vector()->length() == 2); 13850 format %{ "LI $dst, -1 \t// replicate4C" %} 13851 size(4); 13852 ins_encode %{ 13853 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13854 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13855 %} 13856 ins_pipe(pipe_class_default); 13857 %} 13858 13859 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13860 match(Set dst (ReplicateI src)); 13861 predicate(n->as_Vector()->length() == 4); 13862 ins_cost(2 * DEFAULT_COST); 13863 13864 expand %{ 13865 iRegLdst tmpL; 13866 vecX tmpV; 13867 immI8 zero %{ (int) 0 %} 13868 moveReg(tmpL, src); 13869 repl32(tmpL); 13870 mtvsrd(tmpV, tmpL); 13871 xxpermdi(dst, tmpV, tmpV, zero); 13872 %} 13873 %} 13874 13875 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13876 match(Set dst (ReplicateI zero)); 13877 predicate(n->as_Vector()->length() == 4); 13878 13879 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13880 size(4); 13881 ins_encode %{ 13882 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13883 %} 13884 ins_pipe(pipe_class_default); 13885 %} 13886 13887 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13888 match(Set dst (ReplicateI src)); 13889 predicate(n->as_Vector()->length() == 4); 13890 13891 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13892 size(4); 13893 ins_encode %{ 13894 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13895 %} 13896 ins_pipe(pipe_class_default); 13897 %} 13898 13899 // Move float to int register via stack, replicate. 13900 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13901 match(Set dst (ReplicateF src)); 13902 predicate(n->as_Vector()->length() == 2); 13903 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13904 expand %{ 13905 stackSlotL tmpS; 13906 iRegIdst tmpI; 13907 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13908 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13909 moveReg(dst, tmpI); // Move int to long reg. 13910 repl32(dst); // Replicate bitpattern. 13911 %} 13912 %} 13913 13914 // Replicate scalar constant to packed float values in Double register 13915 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13916 match(Set dst (ReplicateF src)); 13917 predicate(n->as_Vector()->length() == 2); 13918 ins_cost(5 * DEFAULT_COST); 13919 13920 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13921 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13922 %} 13923 13924 // Replicate scalar zero constant to packed float values in Double register 13925 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13926 match(Set dst (ReplicateF zero)); 13927 predicate(n->as_Vector()->length() == 2); 13928 13929 format %{ "LI $dst, #0 \t// replicate2F" %} 13930 ins_encode %{ 13931 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13932 __ li($dst$$Register, 0x0); 13933 %} 13934 ins_pipe(pipe_class_default); 13935 %} 13936 13937 13938 //----------Overflow Math Instructions----------------------------------------- 13939 13940 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 13941 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 13942 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 13943 13944 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13945 match(Set cr0 (OverflowAddL op1 op2)); 13946 13947 format %{ "add_ $op1, $op2\t# overflow check long" %} 13948 ins_encode %{ 13949 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13950 __ li(R0, 0); 13951 __ mtxer(R0); // clear XER.SO 13952 __ addo_(R0, $op1$$Register, $op2$$Register); 13953 %} 13954 ins_pipe(pipe_class_default); 13955 %} 13956 13957 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13958 match(Set cr0 (OverflowSubL op1 op2)); 13959 13960 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 13961 ins_encode %{ 13962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13963 __ li(R0, 0); 13964 __ mtxer(R0); // clear XER.SO 13965 __ subfo_(R0, $op2$$Register, $op1$$Register); 13966 %} 13967 ins_pipe(pipe_class_default); 13968 %} 13969 13970 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 13971 match(Set cr0 (OverflowSubL zero op2)); 13972 13973 format %{ "nego_ R0, $op2\t# overflow check long" %} 13974 ins_encode %{ 13975 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13976 __ li(R0, 0); 13977 __ mtxer(R0); // clear XER.SO 13978 __ nego_(R0, $op2$$Register); 13979 %} 13980 ins_pipe(pipe_class_default); 13981 %} 13982 13983 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13984 match(Set cr0 (OverflowMulL op1 op2)); 13985 13986 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 13987 ins_encode %{ 13988 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13989 __ li(R0, 0); 13990 __ mtxer(R0); // clear XER.SO 13991 __ mulldo_(R0, $op1$$Register, $op2$$Register); 13992 %} 13993 ins_pipe(pipe_class_default); 13994 %} 13995 13996 13997 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 13998 match(Set dst (ReplicateF src)); 13999 predicate(n->as_Vector()->length() == 4); 14000 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14001 expand %{ 14002 stackSlotL tmpS; 14003 iRegIdst tmpI; 14004 iRegLdst tmpL; 14005 vecX tmpV; 14006 immI8 zero %{ (int) 0 %} 14007 14008 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14009 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14010 moveReg(tmpL, tmpI); // Move int to long reg. 14011 repl32(tmpL); // Replicate bitpattern. 14012 mtvsrd(tmpV, tmpL); 14013 xxpermdi(dst, tmpV, tmpV, zero); 14014 %} 14015 %} 14016 14017 instruct repl4F_immF_Ex(vecX dst, immF src) %{ 14018 match(Set dst (ReplicateF src)); 14019 predicate(n->as_Vector()->length() == 4); 14020 ins_cost(10 * DEFAULT_COST); 14021 14022 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase) ); 14023 %} 14024 14025 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14026 match(Set dst (ReplicateF zero)); 14027 predicate(n->as_Vector()->length() == 4); 14028 14029 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14030 ins_encode %{ 14031 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14032 %} 14033 ins_pipe(pipe_class_default); 14034 %} 14035 14036 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14037 match(Set dst (ReplicateD src)); 14038 predicate(n->as_Vector()->length() == 2); 14039 expand %{ 14040 stackSlotL tmpS; 14041 iRegLdst tmpL; 14042 iRegLdst tmp; 14043 vecX tmpV; 14044 immI8 zero %{ (int) 0 %} 14045 moveD2L_reg_stack(tmpS, src); 14046 moveD2L_stack_reg(tmpL, tmpS); 14047 mtvsrd(tmpV, tmpL); 14048 xxpermdi(dst, tmpV, tmpV, zero); 14049 %} 14050 %} 14051 14052 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14053 match(Set dst (ReplicateD zero)); 14054 predicate(n->as_Vector()->length() == 2); 14055 14056 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14057 size(4); 14058 ins_encode %{ 14059 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14060 %} 14061 ins_pipe(pipe_class_default); 14062 %} 14063 14064 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14065 match(Set dst (ReplicateD src)); 14066 predicate(n->as_Vector()->length() == 2); 14067 14068 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14069 size(4); 14070 ins_encode %{ 14071 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14072 %} 14073 ins_pipe(pipe_class_default); 14074 %} 14075 14076 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14077 predicate(false); 14078 effect(DEF dst, USE src); 14079 14080 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14081 size(4); 14082 ins_encode %{ 14083 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14084 %} 14085 ins_pipe(pipe_class_default); 14086 %} 14087 14088 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14089 effect(DEF dst, USE src, USE zero); 14090 14091 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14092 size(4); 14093 ins_encode %{ 14094 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14095 %} 14096 ins_pipe(pipe_class_default); 14097 %} 14098 14099 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14100 effect(DEF dst, USE src1, USE src2, USE zero); 14101 14102 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14103 size(4); 14104 ins_encode %{ 14105 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14106 %} 14107 ins_pipe(pipe_class_default); 14108 %} 14109 14110 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14111 match(Set dst (ReplicateL src)); 14112 predicate(n->as_Vector()->length() == 2); 14113 expand %{ 14114 vecX tmpV; 14115 immI8 zero %{ (int) 0 %} 14116 mtvsrd(tmpV, src); 14117 xxpermdi(dst, tmpV, tmpV, zero); 14118 %} 14119 %} 14120 14121 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14122 match(Set dst (ReplicateL zero)); 14123 predicate(n->as_Vector()->length() == 2); 14124 14125 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14126 size(4); 14127 ins_encode %{ 14128 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14129 %} 14130 ins_pipe(pipe_class_default); 14131 %} 14132 14133 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14134 match(Set dst (ReplicateL src)); 14135 predicate(n->as_Vector()->length() == 2); 14136 14137 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14138 size(4); 14139 ins_encode %{ 14140 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14141 %} 14142 ins_pipe(pipe_class_default); 14143 %} 14144 14145 // ============================================================================ 14146 // Safepoint Instruction 14147 14148 instruct safePoint_poll(iRegPdst poll) %{ 14149 match(SafePoint poll); 14150 predicate(LoadPollAddressFromThread); 14151 14152 // It caused problems to add the effect that r0 is killed, but this 14153 // effect no longer needs to be mentioned, since r0 is not contained 14154 // in a reg_class. 14155 14156 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14157 size(4); 14158 ins_encode( enc_poll(0x0, poll) ); 14159 ins_pipe(pipe_class_default); 14160 %} 14161 14162 // Safepoint without per-thread support. Load address of page to poll 14163 // as constant. 14164 // Rscratch2RegP is R12. 14165 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 14166 // a seperate node so that the oop map is at the right location. 14167 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 14168 match(SafePoint poll); 14169 predicate(!LoadPollAddressFromThread); 14170 14171 // It caused problems to add the effect that r0 is killed, but this 14172 // effect no longer needs to be mentioned, since r0 is not contained 14173 // in a reg_class. 14174 14175 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 14176 ins_encode( enc_poll(0x0, poll) ); 14177 ins_pipe(pipe_class_default); 14178 %} 14179 14180 // ============================================================================ 14181 // Call Instructions 14182 14183 // Call Java Static Instruction 14184 14185 // Schedulable version of call static node. 14186 instruct CallStaticJavaDirect(method meth) %{ 14187 match(CallStaticJava); 14188 effect(USE meth); 14189 ins_cost(CALL_COST); 14190 14191 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14192 14193 format %{ "CALL,static $meth \t// ==> " %} 14194 size(4); 14195 ins_encode( enc_java_static_call(meth) ); 14196 ins_pipe(pipe_class_call); 14197 %} 14198 14199 // Call Java Dynamic Instruction 14200 14201 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14202 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14203 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14204 // The call destination must still be placed in the constant pool. 14205 instruct CallDynamicJavaDirectSched(method meth) %{ 14206 match(CallDynamicJava); // To get all the data fields we need ... 14207 effect(USE meth); 14208 predicate(false); // ... but never match. 14209 14210 ins_field_load_ic_hi_node(loadConL_hiNode*); 14211 ins_field_load_ic_node(loadConLNode*); 14212 ins_num_consts(1 /* 1 patchable constant: call destination */); 14213 14214 format %{ "BL \t// dynamic $meth ==> " %} 14215 size(4); 14216 ins_encode( enc_java_dynamic_call_sched(meth) ); 14217 ins_pipe(pipe_class_call); 14218 %} 14219 14220 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14221 // We use postalloc expanded calls if we use inline caches 14222 // and do not update method data. 14223 // 14224 // This instruction has two constants: inline cache (IC) and call destination. 14225 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14226 // one constant. 14227 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14228 match(CallDynamicJava); 14229 effect(USE meth); 14230 predicate(UseInlineCaches); 14231 ins_cost(CALL_COST); 14232 14233 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14234 14235 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14236 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14237 %} 14238 14239 // Compound version of call dynamic java 14240 // We use postalloc expanded calls if we use inline caches 14241 // and do not update method data. 14242 instruct CallDynamicJavaDirect(method meth) %{ 14243 match(CallDynamicJava); 14244 effect(USE meth); 14245 predicate(!UseInlineCaches); 14246 ins_cost(CALL_COST); 14247 14248 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14249 ins_num_consts(4); 14250 14251 format %{ "CALL,dynamic $meth \t// ==> " %} 14252 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14253 ins_pipe(pipe_class_call); 14254 %} 14255 14256 // Call Runtime Instruction 14257 14258 instruct CallRuntimeDirect(method meth) %{ 14259 match(CallRuntime); 14260 effect(USE meth); 14261 ins_cost(CALL_COST); 14262 14263 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14264 // env for callee, C-toc. 14265 ins_num_consts(3); 14266 14267 format %{ "CALL,runtime" %} 14268 ins_encode( enc_java_to_runtime_call(meth) ); 14269 ins_pipe(pipe_class_call); 14270 %} 14271 14272 // Call Leaf 14273 14274 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14275 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14276 effect(DEF dst, USE src); 14277 14278 ins_num_consts(1); 14279 14280 format %{ "MTCTR $src" %} 14281 size(4); 14282 ins_encode( enc_leaf_call_mtctr(src) ); 14283 ins_pipe(pipe_class_default); 14284 %} 14285 14286 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14287 instruct CallLeafDirect(method meth) %{ 14288 match(CallLeaf); // To get the data all the data fields we need ... 14289 effect(USE meth); 14290 predicate(false); // but never match. 14291 14292 format %{ "BCTRL \t// leaf call $meth ==> " %} 14293 size(4); 14294 ins_encode %{ 14295 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14296 __ bctrl(); 14297 %} 14298 ins_pipe(pipe_class_call); 14299 %} 14300 14301 // postalloc expand of CallLeafDirect. 14302 // Load adress to call from TOC, then bl to it. 14303 instruct CallLeafDirect_Ex(method meth) %{ 14304 match(CallLeaf); 14305 effect(USE meth); 14306 ins_cost(CALL_COST); 14307 14308 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14309 // env for callee, C-toc. 14310 ins_num_consts(3); 14311 14312 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14313 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14314 %} 14315 14316 // Call runtime without safepoint - same as CallLeaf. 14317 // postalloc expand of CallLeafNoFPDirect. 14318 // Load adress to call from TOC, then bl to it. 14319 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14320 match(CallLeafNoFP); 14321 effect(USE meth); 14322 ins_cost(CALL_COST); 14323 14324 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14325 // env for callee, C-toc. 14326 ins_num_consts(3); 14327 14328 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14329 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14330 %} 14331 14332 // Tail Call; Jump from runtime stub to Java code. 14333 // Also known as an 'interprocedural jump'. 14334 // Target of jump will eventually return to caller. 14335 // TailJump below removes the return address. 14336 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14337 match(TailCall jump_target method_oop); 14338 ins_cost(CALL_COST); 14339 14340 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14341 "BCTR \t// tail call" %} 14342 size(8); 14343 ins_encode %{ 14344 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14345 __ mtctr($jump_target$$Register); 14346 __ bctr(); 14347 %} 14348 ins_pipe(pipe_class_call); 14349 %} 14350 14351 // Return Instruction 14352 instruct Ret() %{ 14353 match(Return); 14354 format %{ "BLR \t// branch to link register" %} 14355 size(4); 14356 ins_encode %{ 14357 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14358 // LR is restored in MachEpilogNode. Just do the RET here. 14359 __ blr(); 14360 %} 14361 ins_pipe(pipe_class_default); 14362 %} 14363 14364 // Tail Jump; remove the return address; jump to target. 14365 // TailCall above leaves the return address around. 14366 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14367 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14368 // "restore" before this instruction (in Epilogue), we need to materialize it 14369 // in %i0. 14370 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14371 match(TailJump jump_target ex_oop); 14372 ins_cost(CALL_COST); 14373 14374 format %{ "LD R4_ARG2 = LR\n\t" 14375 "MTCTR $jump_target\n\t" 14376 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14377 size(12); 14378 ins_encode %{ 14379 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14380 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14381 __ mtctr($jump_target$$Register); 14382 __ bctr(); 14383 %} 14384 ins_pipe(pipe_class_call); 14385 %} 14386 14387 // Create exception oop: created by stack-crawling runtime code. 14388 // Created exception is now available to this handler, and is setup 14389 // just prior to jumping to this handler. No code emitted. 14390 instruct CreateException(rarg1RegP ex_oop) %{ 14391 match(Set ex_oop (CreateEx)); 14392 ins_cost(0); 14393 14394 format %{ " -- \t// exception oop; no code emitted" %} 14395 size(0); 14396 ins_encode( /*empty*/ ); 14397 ins_pipe(pipe_class_default); 14398 %} 14399 14400 // Rethrow exception: The exception oop will come in the first 14401 // argument position. Then JUMP (not call) to the rethrow stub code. 14402 instruct RethrowException() %{ 14403 match(Rethrow); 14404 ins_cost(CALL_COST); 14405 14406 format %{ "Jmp rethrow_stub" %} 14407 ins_encode %{ 14408 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14409 cbuf.set_insts_mark(); 14410 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14411 %} 14412 ins_pipe(pipe_class_call); 14413 %} 14414 14415 // Die now. 14416 instruct ShouldNotReachHere() %{ 14417 match(Halt); 14418 ins_cost(CALL_COST); 14419 14420 format %{ "ShouldNotReachHere" %} 14421 size(4); 14422 ins_encode %{ 14423 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14424 __ trap_should_not_reach_here(); 14425 %} 14426 ins_pipe(pipe_class_default); 14427 %} 14428 14429 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14430 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14431 // Get a DEF on threadRegP, no costs, no encoding, use 14432 // 'ins_should_rematerialize(true)' to avoid spilling. 14433 instruct tlsLoadP(threadRegP dst) %{ 14434 match(Set dst (ThreadLocal)); 14435 ins_cost(0); 14436 14437 ins_should_rematerialize(true); 14438 14439 format %{ " -- \t// $dst=Thread::current(), empty" %} 14440 size(0); 14441 ins_encode( /*empty*/ ); 14442 ins_pipe(pipe_class_empty); 14443 %} 14444 14445 //---Some PPC specific nodes--------------------------------------------------- 14446 14447 // Stop a group. 14448 instruct endGroup() %{ 14449 ins_cost(0); 14450 14451 ins_is_nop(true); 14452 14453 format %{ "End Bundle (ori r1, r1, 0)" %} 14454 size(4); 14455 ins_encode %{ 14456 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14457 __ endgroup(); 14458 %} 14459 ins_pipe(pipe_class_default); 14460 %} 14461 14462 // Nop instructions 14463 14464 instruct fxNop() %{ 14465 ins_cost(0); 14466 14467 ins_is_nop(true); 14468 14469 format %{ "fxNop" %} 14470 size(4); 14471 ins_encode %{ 14472 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14473 __ nop(); 14474 %} 14475 ins_pipe(pipe_class_default); 14476 %} 14477 14478 instruct fpNop0() %{ 14479 ins_cost(0); 14480 14481 ins_is_nop(true); 14482 14483 format %{ "fpNop0" %} 14484 size(4); 14485 ins_encode %{ 14486 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14487 __ fpnop0(); 14488 %} 14489 ins_pipe(pipe_class_default); 14490 %} 14491 14492 instruct fpNop1() %{ 14493 ins_cost(0); 14494 14495 ins_is_nop(true); 14496 14497 format %{ "fpNop1" %} 14498 size(4); 14499 ins_encode %{ 14500 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14501 __ fpnop1(); 14502 %} 14503 ins_pipe(pipe_class_default); 14504 %} 14505 14506 instruct brNop0() %{ 14507 ins_cost(0); 14508 size(4); 14509 format %{ "brNop0" %} 14510 ins_encode %{ 14511 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14512 __ brnop0(); 14513 %} 14514 ins_is_nop(true); 14515 ins_pipe(pipe_class_default); 14516 %} 14517 14518 instruct brNop1() %{ 14519 ins_cost(0); 14520 14521 ins_is_nop(true); 14522 14523 format %{ "brNop1" %} 14524 size(4); 14525 ins_encode %{ 14526 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14527 __ brnop1(); 14528 %} 14529 ins_pipe(pipe_class_default); 14530 %} 14531 14532 instruct brNop2() %{ 14533 ins_cost(0); 14534 14535 ins_is_nop(true); 14536 14537 format %{ "brNop2" %} 14538 size(4); 14539 ins_encode %{ 14540 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14541 __ brnop2(); 14542 %} 14543 ins_pipe(pipe_class_default); 14544 %} 14545 14546 //----------PEEPHOLE RULES----------------------------------------------------- 14547 // These must follow all instruction definitions as they use the names 14548 // defined in the instructions definitions. 14549 // 14550 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14551 // 14552 // peepconstraint %{ 14553 // (instruction_number.operand_name relational_op instruction_number.operand_name 14554 // [, ...] ); 14555 // // instruction numbers are zero-based using left to right order in peepmatch 14556 // 14557 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14558 // // provide an instruction_number.operand_name for each operand that appears 14559 // // in the replacement instruction's match rule 14560 // 14561 // ---------VM FLAGS--------------------------------------------------------- 14562 // 14563 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14564 // 14565 // Each peephole rule is given an identifying number starting with zero and 14566 // increasing by one in the order seen by the parser. An individual peephole 14567 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14568 // on the command-line. 14569 // 14570 // ---------CURRENT LIMITATIONS---------------------------------------------- 14571 // 14572 // Only match adjacent instructions in same basic block 14573 // Only equality constraints 14574 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14575 // Only one replacement instruction 14576 // 14577 // ---------EXAMPLE---------------------------------------------------------- 14578 // 14579 // // pertinent parts of existing instructions in architecture description 14580 // instruct movI(eRegI dst, eRegI src) %{ 14581 // match(Set dst (CopyI src)); 14582 // %} 14583 // 14584 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14585 // match(Set dst (AddI dst src)); 14586 // effect(KILL cr); 14587 // %} 14588 // 14589 // // Change (inc mov) to lea 14590 // peephole %{ 14591 // // increment preceeded by register-register move 14592 // peepmatch ( incI_eReg movI ); 14593 // // require that the destination register of the increment 14594 // // match the destination register of the move 14595 // peepconstraint ( 0.dst == 1.dst ); 14596 // // construct a replacement instruction that sets 14597 // // the destination to ( move's source register + one ) 14598 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14599 // %} 14600 // 14601 // Implementation no longer uses movX instructions since 14602 // machine-independent system no longer uses CopyX nodes. 14603 // 14604 // peephole %{ 14605 // peepmatch ( incI_eReg movI ); 14606 // peepconstraint ( 0.dst == 1.dst ); 14607 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14608 // %} 14609 // 14610 // peephole %{ 14611 // peepmatch ( decI_eReg movI ); 14612 // peepconstraint ( 0.dst == 1.dst ); 14613 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14614 // %} 14615 // 14616 // peephole %{ 14617 // peepmatch ( addI_eReg_imm movI ); 14618 // peepconstraint ( 0.dst == 1.dst ); 14619 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14620 // %} 14621 // 14622 // peephole %{ 14623 // peepmatch ( addP_eReg_imm movP ); 14624 // peepconstraint ( 0.dst == 1.dst ); 14625 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14626 // %} 14627 14628 // // Change load of spilled value to only a spill 14629 // instruct storeI(memory mem, eRegI src) %{ 14630 // match(Set mem (StoreI mem src)); 14631 // %} 14632 // 14633 // instruct loadI(eRegI dst, memory mem) %{ 14634 // match(Set dst (LoadI mem)); 14635 // %} 14636 // 14637 peephole %{ 14638 peepmatch ( loadI storeI ); 14639 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14640 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14641 %} 14642 14643 peephole %{ 14644 peepmatch ( loadL storeL ); 14645 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14646 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14647 %} 14648 14649 peephole %{ 14650 peepmatch ( loadP storeP ); 14651 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14652 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14653 %} 14654 14655 //----------SMARTSPILL RULES--------------------------------------------------- 14656 // These must follow all instruction definitions as they use the names 14657 // defined in the instructions definitions.