1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 // ---------------------------- 258 // Vector-Scalar Registers 259 // ---------------------------- 260 reg_def VSR0 ( SOC, SOC, Op_VecX, 0, NULL); 261 reg_def VSR1 ( SOC, SOC, Op_VecX, 1, NULL); 262 reg_def VSR2 ( SOC, SOC, Op_VecX, 2, NULL); 263 reg_def VSR3 ( SOC, SOC, Op_VecX, 3, NULL); 264 reg_def VSR4 ( SOC, SOC, Op_VecX, 4, NULL); 265 reg_def VSR5 ( SOC, SOC, Op_VecX, 5, NULL); 266 reg_def VSR6 ( SOC, SOC, Op_VecX, 6, NULL); 267 reg_def VSR7 ( SOC, SOC, Op_VecX, 7, NULL); 268 reg_def VSR8 ( SOC, SOC, Op_VecX, 8, NULL); 269 reg_def VSR9 ( SOC, SOC, Op_VecX, 9, NULL); 270 reg_def VSR10 ( SOC, SOC, Op_VecX, 10, NULL); 271 reg_def VSR11 ( SOC, SOC, Op_VecX, 11, NULL); 272 reg_def VSR12 ( SOC, SOC, Op_VecX, 12, NULL); 273 reg_def VSR13 ( SOC, SOC, Op_VecX, 13, NULL); 274 reg_def VSR14 ( SOC, SOC, Op_VecX, 14, NULL); 275 reg_def VSR15 ( SOC, SOC, Op_VecX, 15, NULL); 276 reg_def VSR16 ( SOC, SOC, Op_VecX, 16, NULL); 277 reg_def VSR17 ( SOC, SOC, Op_VecX, 17, NULL); 278 reg_def VSR18 ( SOC, SOC, Op_VecX, 18, NULL); 279 reg_def VSR19 ( SOC, SOC, Op_VecX, 19, NULL); 280 reg_def VSR20 ( SOC, SOC, Op_VecX, 20, NULL); 281 reg_def VSR21 ( SOC, SOC, Op_VecX, 21, NULL); 282 reg_def VSR22 ( SOC, SOC, Op_VecX, 22, NULL); 283 reg_def VSR23 ( SOC, SOC, Op_VecX, 23, NULL); 284 reg_def VSR24 ( SOC, SOC, Op_VecX, 24, NULL); 285 reg_def VSR25 ( SOC, SOC, Op_VecX, 25, NULL); 286 reg_def VSR26 ( SOC, SOC, Op_VecX, 26, NULL); 287 reg_def VSR27 ( SOC, SOC, Op_VecX, 27, NULL); 288 reg_def VSR28 ( SOC, SOC, Op_VecX, 28, NULL); 289 reg_def VSR29 ( SOC, SOC, Op_VecX, 29, NULL); 290 reg_def VSR30 ( SOC, SOC, Op_VecX, 30, NULL); 291 reg_def VSR31 ( SOC, SOC, Op_VecX, 31, NULL); 292 reg_def VSR32 ( SOC, SOC, Op_VecX, 32, NULL); 293 reg_def VSR33 ( SOC, SOC, Op_VecX, 33, NULL); 294 reg_def VSR34 ( SOC, SOC, Op_VecX, 34, NULL); 295 reg_def VSR35 ( SOC, SOC, Op_VecX, 35, NULL); 296 reg_def VSR36 ( SOC, SOC, Op_VecX, 36, NULL); 297 reg_def VSR37 ( SOC, SOC, Op_VecX, 37, NULL); 298 reg_def VSR38 ( SOC, SOC, Op_VecX, 38, NULL); 299 reg_def VSR39 ( SOC, SOC, Op_VecX, 39, NULL); 300 reg_def VSR40 ( SOC, SOC, Op_VecX, 40, NULL); 301 reg_def VSR41 ( SOC, SOC, Op_VecX, 41, NULL); 302 reg_def VSR42 ( SOC, SOC, Op_VecX, 42, NULL); 303 reg_def VSR43 ( SOC, SOC, Op_VecX, 43, NULL); 304 reg_def VSR44 ( SOC, SOC, Op_VecX, 44, NULL); 305 reg_def VSR45 ( SOC, SOC, Op_VecX, 45, NULL); 306 reg_def VSR46 ( SOC, SOC, Op_VecX, 46, NULL); 307 reg_def VSR47 ( SOC, SOC, Op_VecX, 47, NULL); 308 reg_def VSR48 ( SOC, SOC, Op_VecX, 48, NULL); 309 reg_def VSR49 ( SOC, SOC, Op_VecX, 49, NULL); 310 reg_def VSR50 ( SOC, SOC, Op_VecX, 50, NULL); 311 reg_def VSR51 ( SOC, SOC, Op_VecX, 51, NULL); 312 reg_def VSR52 ( SOC, SOC, Op_VecX, 52, NULL); 313 reg_def VSR53 ( SOC, SOC, Op_VecX, 53, NULL); 314 reg_def VSR54 ( SOC, SOC, Op_VecX, 54, NULL); 315 reg_def VSR55 ( SOC, SOC, Op_VecX, 55, NULL); 316 reg_def VSR56 ( SOC, SOC, Op_VecX, 56, NULL); 317 reg_def VSR57 ( SOC, SOC, Op_VecX, 57, NULL); 318 reg_def VSR58 ( SOC, SOC, Op_VecX, 58, NULL); 319 reg_def VSR59 ( SOC, SOC, Op_VecX, 59, NULL); 320 reg_def VSR60 ( SOC, SOC, Op_VecX, 60, NULL); 321 reg_def VSR61 ( SOC, SOC, Op_VecX, 61, NULL); 322 reg_def VSR62 ( SOC, SOC, Op_VecX, 62, NULL); 323 reg_def VSR63 ( SOC, SOC, Op_VecX, 63, NULL); 324 325 // ---------------------------- 326 // Specify priority of register selection within phases of register 327 // allocation. Highest priority is first. A useful heuristic is to 328 // give registers a low priority when they are required by machine 329 // instructions, like EAX and EDX on I486, and choose no-save registers 330 // before save-on-call, & save-on-call before save-on-entry. Registers 331 // which participate in fixed calling sequences should come last. 332 // Registers which are used as pairs must fall on an even boundary. 333 334 // It's worth about 1% on SPEC geomean to get this right. 335 336 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 337 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 338 // R3_num. Therefore, R3_num may not be (and in reality is not) 339 // the same as R3->encoding()! Furthermore, we cannot make any 340 // assumptions on ordering, e.g. R3_num may be less than R2_num. 341 // Additionally, the function 342 // static enum RC rc_class(OptoReg::Name reg ) 343 // maps a given <register>_num value to its chunk type (except for flags) 344 // and its current implementation relies on chunk0 and chunk1 having a 345 // size of 64 each. 346 347 // If you change this allocation class, please have a look at the 348 // default values for the parameters RoundRobinIntegerRegIntervalStart 349 // and RoundRobinFloatRegIntervalStart 350 351 alloc_class chunk0 ( 352 // Chunk0 contains *all* 64 integer registers halves. 353 354 // "non-volatile" registers 355 R14, R14_H, 356 R15, R15_H, 357 R17, R17_H, 358 R18, R18_H, 359 R19, R19_H, 360 R20, R20_H, 361 R21, R21_H, 362 R22, R22_H, 363 R23, R23_H, 364 R24, R24_H, 365 R25, R25_H, 366 R26, R26_H, 367 R27, R27_H, 368 R28, R28_H, 369 R29, R29_H, 370 R30, R30_H, 371 R31, R31_H, 372 373 // scratch/special registers 374 R11, R11_H, 375 R12, R12_H, 376 377 // argument registers 378 R10, R10_H, 379 R9, R9_H, 380 R8, R8_H, 381 R7, R7_H, 382 R6, R6_H, 383 R5, R5_H, 384 R4, R4_H, 385 R3, R3_H, 386 387 // special registers, not available for allocation 388 R16, R16_H, // R16_thread 389 R13, R13_H, // system thread id 390 R2, R2_H, // may be used for TOC 391 R1, R1_H, // SP 392 R0, R0_H // R0 (scratch) 393 ); 394 395 // If you change this allocation class, please have a look at the 396 // default values for the parameters RoundRobinIntegerRegIntervalStart 397 // and RoundRobinFloatRegIntervalStart 398 399 alloc_class chunk1 ( 400 // Chunk1 contains *all* 64 floating-point registers halves. 401 402 // scratch register 403 F0, F0_H, 404 405 // argument registers 406 F13, F13_H, 407 F12, F12_H, 408 F11, F11_H, 409 F10, F10_H, 410 F9, F9_H, 411 F8, F8_H, 412 F7, F7_H, 413 F6, F6_H, 414 F5, F5_H, 415 F4, F4_H, 416 F3, F3_H, 417 F2, F2_H, 418 F1, F1_H, 419 420 // non-volatile registers 421 F14, F14_H, 422 F15, F15_H, 423 F16, F16_H, 424 F17, F17_H, 425 F18, F18_H, 426 F19, F19_H, 427 F20, F20_H, 428 F21, F21_H, 429 F22, F22_H, 430 F23, F23_H, 431 F24, F24_H, 432 F25, F25_H, 433 F26, F26_H, 434 F27, F27_H, 435 F28, F28_H, 436 F29, F29_H, 437 F30, F30_H, 438 F31, F31_H 439 ); 440 441 alloc_class chunk2 ( 442 // Chunk2 contains *all* 8 condition code registers. 443 444 CCR0, 445 CCR1, 446 CCR2, 447 CCR3, 448 CCR4, 449 CCR5, 450 CCR6, 451 CCR7 452 ); 453 454 alloc_class chunk3 ( 455 VSR0, 456 VSR1, 457 VSR2, 458 VSR3, 459 VSR4, 460 VSR5, 461 VSR6, 462 VSR7, 463 VSR8, 464 VSR9, 465 VSR10, 466 VSR11, 467 VSR12, 468 VSR13, 469 VSR14, 470 VSR15, 471 VSR16, 472 VSR17, 473 VSR18, 474 VSR19, 475 VSR20, 476 VSR21, 477 VSR22, 478 VSR23, 479 VSR24, 480 VSR25, 481 VSR26, 482 VSR27, 483 VSR28, 484 VSR29, 485 VSR30, 486 VSR31, 487 VSR32, 488 VSR33, 489 VSR34, 490 VSR35, 491 VSR36, 492 VSR37, 493 VSR38, 494 VSR39, 495 VSR40, 496 VSR41, 497 VSR42, 498 VSR43, 499 VSR44, 500 VSR45, 501 VSR46, 502 VSR47, 503 VSR48, 504 VSR49, 505 VSR50, 506 VSR51, 507 VSR52, 508 VSR53, 509 VSR54, 510 VSR55, 511 VSR56, 512 VSR57, 513 VSR58, 514 VSR59, 515 VSR60, 516 VSR61, 517 VSR62, 518 VSR63 519 ); 520 521 alloc_class chunk4 ( 522 // special registers 523 // These registers are not allocated, but used for nodes generated by postalloc expand. 524 SR_XER, 525 SR_LR, 526 SR_CTR, 527 SR_VRSAVE, 528 SR_SPEFSCR, 529 SR_PPR 530 ); 531 532 //-------Architecture Description Register Classes----------------------- 533 534 // Several register classes are automatically defined based upon 535 // information in this architecture description. 536 537 // 1) reg_class inline_cache_reg ( as defined in frame section ) 538 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 539 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 540 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 541 // 542 543 // ---------------------------- 544 // 32 Bit Register Classes 545 // ---------------------------- 546 547 // We specify registers twice, once as read/write, and once read-only. 548 // We use the read-only registers for source operands. With this, we 549 // can include preset read only registers in this class, as a hard-coded 550 // '0'-register. (We used to simulate this on ppc.) 551 552 // 32 bit registers that can be read and written i.e. these registers 553 // can be dest (or src) of normal instructions. 554 reg_class bits32_reg_rw( 555 /*R0*/ // R0 556 /*R1*/ // SP 557 R2, // TOC 558 R3, 559 R4, 560 R5, 561 R6, 562 R7, 563 R8, 564 R9, 565 R10, 566 R11, 567 R12, 568 /*R13*/ // system thread id 569 R14, 570 R15, 571 /*R16*/ // R16_thread 572 R17, 573 R18, 574 R19, 575 R20, 576 R21, 577 R22, 578 R23, 579 R24, 580 R25, 581 R26, 582 R27, 583 R28, 584 /*R29,*/ // global TOC 585 R30, 586 R31 587 ); 588 589 // 32 bit registers that can only be read i.e. these registers can 590 // only be src of all instructions. 591 reg_class bits32_reg_ro( 592 /*R0*/ // R0 593 /*R1*/ // SP 594 R2 // TOC 595 R3, 596 R4, 597 R5, 598 R6, 599 R7, 600 R8, 601 R9, 602 R10, 603 R11, 604 R12, 605 /*R13*/ // system thread id 606 R14, 607 R15, 608 /*R16*/ // R16_thread 609 R17, 610 R18, 611 R19, 612 R20, 613 R21, 614 R22, 615 R23, 616 R24, 617 R25, 618 R26, 619 R27, 620 R28, 621 /*R29,*/ 622 R30, 623 R31 624 ); 625 626 reg_class rscratch1_bits32_reg(R11); 627 reg_class rscratch2_bits32_reg(R12); 628 reg_class rarg1_bits32_reg(R3); 629 reg_class rarg2_bits32_reg(R4); 630 reg_class rarg3_bits32_reg(R5); 631 reg_class rarg4_bits32_reg(R6); 632 633 // ---------------------------- 634 // 64 Bit Register Classes 635 // ---------------------------- 636 // 64-bit build means 64-bit pointers means hi/lo pairs 637 638 reg_class rscratch1_bits64_reg(R11_H, R11); 639 reg_class rscratch2_bits64_reg(R12_H, R12); 640 reg_class rarg1_bits64_reg(R3_H, R3); 641 reg_class rarg2_bits64_reg(R4_H, R4); 642 reg_class rarg3_bits64_reg(R5_H, R5); 643 reg_class rarg4_bits64_reg(R6_H, R6); 644 // Thread register, 'written' by tlsLoadP, see there. 645 reg_class thread_bits64_reg(R16_H, R16); 646 647 reg_class r19_bits64_reg(R19_H, R19); 648 649 // 64 bit registers that can be read and written i.e. these registers 650 // can be dest (or src) of normal instructions. 651 reg_class bits64_reg_rw( 652 /*R0_H, R0*/ // R0 653 /*R1_H, R1*/ // SP 654 R2_H, R2, // TOC 655 R3_H, R3, 656 R4_H, R4, 657 R5_H, R5, 658 R6_H, R6, 659 R7_H, R7, 660 R8_H, R8, 661 R9_H, R9, 662 R10_H, R10, 663 R11_H, R11, 664 R12_H, R12, 665 /*R13_H, R13*/ // system thread id 666 R14_H, R14, 667 R15_H, R15, 668 /*R16_H, R16*/ // R16_thread 669 R17_H, R17, 670 R18_H, R18, 671 R19_H, R19, 672 R20_H, R20, 673 R21_H, R21, 674 R22_H, R22, 675 R23_H, R23, 676 R24_H, R24, 677 R25_H, R25, 678 R26_H, R26, 679 R27_H, R27, 680 R28_H, R28, 681 /*R29_H, R29,*/ 682 R30_H, R30, 683 R31_H, R31 684 ); 685 686 // 64 bit registers used excluding r2, r11 and r12 687 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 688 // r2, r11 and r12 internally. 689 reg_class bits64_reg_leaf_call( 690 /*R0_H, R0*/ // R0 691 /*R1_H, R1*/ // SP 692 /*R2_H, R2*/ // TOC 693 R3_H, R3, 694 R4_H, R4, 695 R5_H, R5, 696 R6_H, R6, 697 R7_H, R7, 698 R8_H, R8, 699 R9_H, R9, 700 R10_H, R10, 701 /*R11_H, R11*/ 702 /*R12_H, R12*/ 703 /*R13_H, R13*/ // system thread id 704 R14_H, R14, 705 R15_H, R15, 706 /*R16_H, R16*/ // R16_thread 707 R17_H, R17, 708 R18_H, R18, 709 R19_H, R19, 710 R20_H, R20, 711 R21_H, R21, 712 R22_H, R22, 713 R23_H, R23, 714 R24_H, R24, 715 R25_H, R25, 716 R26_H, R26, 717 R27_H, R27, 718 R28_H, R28, 719 /*R29_H, R29,*/ 720 R30_H, R30, 721 R31_H, R31 722 ); 723 724 // Used to hold the TOC to avoid collisions with expanded DynamicCall 725 // which uses r19 as inline cache internally and expanded LeafCall which uses 726 // r2, r11 and r12 internally. 727 reg_class bits64_constant_table_base( 728 /*R0_H, R0*/ // R0 729 /*R1_H, R1*/ // SP 730 /*R2_H, R2*/ // TOC 731 R3_H, R3, 732 R4_H, R4, 733 R5_H, R5, 734 R6_H, R6, 735 R7_H, R7, 736 R8_H, R8, 737 R9_H, R9, 738 R10_H, R10, 739 /*R11_H, R11*/ 740 /*R12_H, R12*/ 741 /*R13_H, R13*/ // system thread id 742 R14_H, R14, 743 R15_H, R15, 744 /*R16_H, R16*/ // R16_thread 745 R17_H, R17, 746 R18_H, R18, 747 /*R19_H, R19*/ 748 R20_H, R20, 749 R21_H, R21, 750 R22_H, R22, 751 R23_H, R23, 752 R24_H, R24, 753 R25_H, R25, 754 R26_H, R26, 755 R27_H, R27, 756 R28_H, R28, 757 /*R29_H, R29,*/ 758 R30_H, R30, 759 R31_H, R31 760 ); 761 762 // 64 bit registers that can only be read i.e. these registers can 763 // only be src of all instructions. 764 reg_class bits64_reg_ro( 765 /*R0_H, R0*/ // R0 766 R1_H, R1, 767 R2_H, R2, // TOC 768 R3_H, R3, 769 R4_H, R4, 770 R5_H, R5, 771 R6_H, R6, 772 R7_H, R7, 773 R8_H, R8, 774 R9_H, R9, 775 R10_H, R10, 776 R11_H, R11, 777 R12_H, R12, 778 /*R13_H, R13*/ // system thread id 779 R14_H, R14, 780 R15_H, R15, 781 R16_H, R16, // R16_thread 782 R17_H, R17, 783 R18_H, R18, 784 R19_H, R19, 785 R20_H, R20, 786 R21_H, R21, 787 R22_H, R22, 788 R23_H, R23, 789 R24_H, R24, 790 R25_H, R25, 791 R26_H, R26, 792 R27_H, R27, 793 R28_H, R28, 794 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 795 R30_H, R30, 796 R31_H, R31 797 ); 798 799 800 // ---------------------------- 801 // Special Class for Condition Code Flags Register 802 803 reg_class int_flags( 804 /*CCR0*/ // scratch 805 /*CCR1*/ // scratch 806 /*CCR2*/ // nv! 807 /*CCR3*/ // nv! 808 /*CCR4*/ // nv! 809 CCR5, 810 CCR6, 811 CCR7 812 ); 813 814 reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823 ); 824 825 reg_class int_flags_CR0(CCR0); 826 reg_class int_flags_CR1(CCR1); 827 reg_class int_flags_CR6(CCR6); 828 reg_class ctr_reg(SR_CTR); 829 830 // ---------------------------- 831 // Float Register Classes 832 // ---------------------------- 833 834 reg_class flt_reg( 835 F0, 836 F1, 837 F2, 838 F3, 839 F4, 840 F5, 841 F6, 842 F7, 843 F8, 844 F9, 845 F10, 846 F11, 847 F12, 848 F13, 849 F14, // nv! 850 F15, // nv! 851 F16, // nv! 852 F17, // nv! 853 F18, // nv! 854 F19, // nv! 855 F20, // nv! 856 F21, // nv! 857 F22, // nv! 858 F23, // nv! 859 F24, // nv! 860 F25, // nv! 861 F26, // nv! 862 F27, // nv! 863 F28, // nv! 864 F29, // nv! 865 F30, // nv! 866 F31 // nv! 867 ); 868 869 // Double precision float registers have virtual `high halves' that 870 // are needed by the allocator. 871 reg_class dbl_reg( 872 F0, F0_H, 873 F1, F1_H, 874 F2, F2_H, 875 F3, F3_H, 876 F4, F4_H, 877 F5, F5_H, 878 F6, F6_H, 879 F7, F7_H, 880 F8, F8_H, 881 F9, F9_H, 882 F10, F10_H, 883 F11, F11_H, 884 F12, F12_H, 885 F13, F13_H, 886 F14, F14_H, // nv! 887 F15, F15_H, // nv! 888 F16, F16_H, // nv! 889 F17, F17_H, // nv! 890 F18, F18_H, // nv! 891 F19, F19_H, // nv! 892 F20, F20_H, // nv! 893 F21, F21_H, // nv! 894 F22, F22_H, // nv! 895 F23, F23_H, // nv! 896 F24, F24_H, // nv! 897 F25, F25_H, // nv! 898 F26, F26_H, // nv! 899 F27, F27_H, // nv! 900 F28, F28_H, // nv! 901 F29, F29_H, // nv! 902 F30, F30_H, // nv! 903 F31, F31_H // nv! 904 ); 905 906 // ---------------------------- 907 // Vector-Scalar Register Class 908 // ---------------------------- 909 910 reg_class vs_reg( 911 VSR32, 912 VSR33, 913 VSR34, 914 VSR35, 915 VSR36, 916 VSR37, 917 VSR38, 918 VSR39, 919 VSR40, 920 VSR41, 921 VSR42, 922 VSR43, 923 VSR44, 924 VSR45, 925 VSR46, 926 VSR47, 927 VSR48, 928 VSR49, 929 VSR50, 930 VSR51 931 // VSR52, // nv! 932 // VSR53, // nv! 933 // VSR54, // nv! 934 // VSR55, // nv! 935 // VSR56, // nv! 936 // VSR57, // nv! 937 // VSR58, // nv! 938 // VSR59, // nv! 939 // VSR60, // nv! 940 // VSR61, // nv! 941 // VSR62, // nv! 942 // VSR63 // nv! 943 ); 944 945 %} 946 947 //----------DEFINITION BLOCK--------------------------------------------------- 948 // Define name --> value mappings to inform the ADLC of an integer valued name 949 // Current support includes integer values in the range [0, 0x7FFFFFFF] 950 // Format: 951 // int_def <name> ( <int_value>, <expression>); 952 // Generated Code in ad_<arch>.hpp 953 // #define <name> (<expression>) 954 // // value == <int_value> 955 // Generated code in ad_<arch>.cpp adlc_verification() 956 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 957 // 958 definitions %{ 959 // The default cost (of an ALU instruction). 960 int_def DEFAULT_COST_LOW ( 30, 30); 961 int_def DEFAULT_COST ( 100, 100); 962 int_def HUGE_COST (1000000, 1000000); 963 964 // Memory refs 965 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 966 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 967 968 // Branches are even more expensive. 969 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 970 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 971 %} 972 973 974 //----------SOURCE BLOCK------------------------------------------------------- 975 // This is a block of C++ code which provides values, functions, and 976 // definitions necessary in the rest of the architecture description. 977 source_hpp %{ 978 // Header information of the source block. 979 // Method declarations/definitions which are used outside 980 // the ad-scope can conveniently be defined here. 981 // 982 // To keep related declarations/definitions/uses close together, 983 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 984 985 // Returns true if Node n is followed by a MemBar node that 986 // will do an acquire. If so, this node must not do the acquire 987 // operation. 988 bool followed_by_acquire(const Node *n); 989 %} 990 991 source %{ 992 993 // Should the Matcher clone shifts on addressing modes, expecting them 994 // to be subsumed into complex addressing expressions or compute them 995 // into registers? 996 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 997 return clone_base_plus_offset_address(m, mstack, address_visited); 998 } 999 1000 void Compile::reshape_address(AddPNode* addp) { 1001 } 1002 1003 // Optimize load-acquire. 1004 // 1005 // Check if acquire is unnecessary due to following operation that does 1006 // acquire anyways. 1007 // Walk the pattern: 1008 // 1009 // n: Load.acq 1010 // | 1011 // MemBarAcquire 1012 // | | 1013 // Proj(ctrl) Proj(mem) 1014 // | | 1015 // MemBarRelease/Volatile 1016 // 1017 bool followed_by_acquire(const Node *load) { 1018 assert(load->is_Load(), "So far implemented only for loads."); 1019 1020 // Find MemBarAcquire. 1021 const Node *mba = NULL; 1022 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1023 const Node *out = load->fast_out(i); 1024 if (out->Opcode() == Op_MemBarAcquire) { 1025 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1026 mba = out; 1027 break; 1028 } 1029 } 1030 if (!mba) return false; 1031 1032 // Find following MemBar node. 1033 // 1034 // The following node must be reachable by control AND memory 1035 // edge to assure no other operations are in between the two nodes. 1036 // 1037 // So first get the Proj node, mem_proj, to use it to iterate forward. 1038 Node *mem_proj = NULL; 1039 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1040 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 1041 assert(mem_proj->is_Proj(), "only projections here"); 1042 ProjNode *proj = mem_proj->as_Proj(); 1043 if (proj->_con == TypeFunc::Memory && 1044 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1045 break; 1046 } 1047 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1048 1049 // Search MemBar behind Proj. If there are other memory operations 1050 // behind the Proj we lost. 1051 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1052 Node *x = mem_proj->fast_out(j); 1053 // Proj might have an edge to a store or load node which precedes the membar. 1054 if (x->is_Mem()) return false; 1055 1056 // On PPC64 release and volatile are implemented by an instruction 1057 // that also has acquire semantics. I.e. there is no need for an 1058 // acquire before these. 1059 int xop = x->Opcode(); 1060 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1061 // Make sure we're not missing Call/Phi/MergeMem by checking 1062 // control edges. The control edge must directly lead back 1063 // to the MemBarAcquire 1064 Node *ctrl_proj = x->in(0); 1065 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1066 return true; 1067 } 1068 } 1069 } 1070 1071 return false; 1072 } 1073 1074 #define __ _masm. 1075 1076 // Tertiary op of a LoadP or StoreP encoding. 1077 #define REGP_OP true 1078 1079 // **************************************************************************** 1080 1081 // REQUIRED FUNCTIONALITY 1082 1083 // !!!!! Special hack to get all type of calls to specify the byte offset 1084 // from the start of the call to the point where the return address 1085 // will point. 1086 1087 // PPC port: Removed use of lazy constant construct. 1088 1089 int MachCallStaticJavaNode::ret_addr_offset() { 1090 // It's only a single branch-and-link instruction. 1091 return 4; 1092 } 1093 1094 int MachCallDynamicJavaNode::ret_addr_offset() { 1095 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1096 // postalloc expanded calls if we use inline caches and do not update method data. 1097 if (UseInlineCaches) 1098 return 4; 1099 1100 int vtable_index = this->_vtable_index; 1101 if (vtable_index < 0) { 1102 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1103 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1104 return 12; 1105 } else { 1106 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1107 return 24; 1108 } 1109 } 1110 1111 int MachCallRuntimeNode::ret_addr_offset() { 1112 #if defined(ABI_ELFv2) 1113 return 28; 1114 #else 1115 return 40; 1116 #endif 1117 } 1118 1119 //============================================================================= 1120 1121 // condition code conversions 1122 1123 static int cc_to_boint(int cc) { 1124 return Assembler::bcondCRbiIs0 | (cc & 8); 1125 } 1126 1127 static int cc_to_inverse_boint(int cc) { 1128 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1129 } 1130 1131 static int cc_to_biint(int cc, int flags_reg) { 1132 return (flags_reg << 2) | (cc & 3); 1133 } 1134 1135 //============================================================================= 1136 1137 // Compute padding required for nodes which need alignment. The padding 1138 // is the number of bytes (not instructions) which will be inserted before 1139 // the instruction. The padding must match the size of a NOP instruction. 1140 1141 // Currently not used on this platform. 1142 1143 //============================================================================= 1144 1145 // Indicate if the safepoint node needs the polling page as an input. 1146 bool SafePointNode::needs_polling_address_input() { 1147 // The address is loaded from thread by a seperate node. 1148 return true; 1149 } 1150 1151 //============================================================================= 1152 1153 // Emit an interrupt that is caught by the debugger (for debugging compiler). 1154 void emit_break(CodeBuffer &cbuf) { 1155 MacroAssembler _masm(&cbuf); 1156 __ illtrap(); 1157 } 1158 1159 #ifndef PRODUCT 1160 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1161 st->print("BREAKPOINT"); 1162 } 1163 #endif 1164 1165 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1166 emit_break(cbuf); 1167 } 1168 1169 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1170 return MachNode::size(ra_); 1171 } 1172 1173 //============================================================================= 1174 1175 void emit_nop(CodeBuffer &cbuf) { 1176 MacroAssembler _masm(&cbuf); 1177 __ nop(); 1178 } 1179 1180 static inline void emit_long(CodeBuffer &cbuf, int value) { 1181 *((int*)(cbuf.insts_end())) = value; 1182 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1183 } 1184 1185 //============================================================================= 1186 1187 %} // interrupt source 1188 1189 source_hpp %{ // Header information of the source block. 1190 1191 //-------------------------------------------------------------- 1192 //---< Used for optimization in Compile::Shorten_branches >--- 1193 //-------------------------------------------------------------- 1194 1195 class CallStubImpl { 1196 1197 public: 1198 1199 // Emit call stub, compiled java to interpreter. 1200 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1201 1202 // Size of call trampoline stub. 1203 // This doesn't need to be accurate to the byte, but it 1204 // must be larger than or equal to the real size of the stub. 1205 static uint size_call_trampoline() { 1206 return MacroAssembler::trampoline_stub_size; 1207 } 1208 1209 // number of relocations needed by a call trampoline stub 1210 static uint reloc_call_trampoline() { 1211 return 5; 1212 } 1213 1214 }; 1215 1216 %} // end source_hpp 1217 1218 source %{ 1219 1220 // Emit a trampoline stub for a call to a target which is too far away. 1221 // 1222 // code sequences: 1223 // 1224 // call-site: 1225 // branch-and-link to <destination> or <trampoline stub> 1226 // 1227 // Related trampoline stub for this call-site in the stub section: 1228 // load the call target from the constant pool 1229 // branch via CTR (LR/link still points to the call-site above) 1230 1231 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1232 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1233 if (stub == NULL) { 1234 ciEnv::current()->record_out_of_memory_failure(); 1235 } 1236 } 1237 1238 //============================================================================= 1239 1240 // Emit an inline branch-and-link call and a related trampoline stub. 1241 // 1242 // code sequences: 1243 // 1244 // call-site: 1245 // branch-and-link to <destination> or <trampoline stub> 1246 // 1247 // Related trampoline stub for this call-site in the stub section: 1248 // load the call target from the constant pool 1249 // branch via CTR (LR/link still points to the call-site above) 1250 // 1251 1252 typedef struct { 1253 int insts_call_instruction_offset; 1254 int ret_addr_offset; 1255 } EmitCallOffsets; 1256 1257 // Emit a branch-and-link instruction that branches to a trampoline. 1258 // - Remember the offset of the branch-and-link instruction. 1259 // - Add a relocation at the branch-and-link instruction. 1260 // - Emit a branch-and-link. 1261 // - Remember the return pc offset. 1262 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1263 EmitCallOffsets offsets = { -1, -1 }; 1264 const int start_offset = __ offset(); 1265 offsets.insts_call_instruction_offset = __ offset(); 1266 1267 // No entry point given, use the current pc. 1268 if (entry_point == NULL) entry_point = __ pc(); 1269 1270 // Put the entry point as a constant into the constant pool. 1271 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1272 if (entry_point_toc_addr == NULL) { 1273 ciEnv::current()->record_out_of_memory_failure(); 1274 return offsets; 1275 } 1276 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1277 1278 // Emit the trampoline stub which will be related to the branch-and-link below. 1279 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1280 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1281 __ relocate(rtype); 1282 1283 // Note: At this point we do not have the address of the trampoline 1284 // stub, and the entry point might be too far away for bl, so __ pc() 1285 // serves as dummy and the bl will be patched later. 1286 __ bl((address) __ pc()); 1287 1288 offsets.ret_addr_offset = __ offset() - start_offset; 1289 1290 return offsets; 1291 } 1292 1293 //============================================================================= 1294 1295 // Factory for creating loadConL* nodes for large/small constant pool. 1296 1297 static inline jlong replicate_immF(float con) { 1298 // Replicate float con 2 times and pack into vector. 1299 int val = *((int*)&con); 1300 jlong lval = val; 1301 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1302 return lval; 1303 } 1304 1305 //============================================================================= 1306 1307 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1308 int Compile::ConstantTable::calculate_table_base_offset() const { 1309 return 0; // absolute addressing, no offset 1310 } 1311 1312 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1313 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1314 iRegPdstOper *op_dst = new iRegPdstOper(); 1315 MachNode *m1 = new loadToc_hiNode(); 1316 MachNode *m2 = new loadToc_loNode(); 1317 1318 m1->add_req(NULL); 1319 m2->add_req(NULL, m1); 1320 m1->_opnds[0] = op_dst; 1321 m2->_opnds[0] = op_dst; 1322 m2->_opnds[1] = op_dst; 1323 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1324 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1325 nodes->push(m1); 1326 nodes->push(m2); 1327 } 1328 1329 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1330 // Is postalloc expanded. 1331 ShouldNotReachHere(); 1332 } 1333 1334 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1335 return 0; 1336 } 1337 1338 #ifndef PRODUCT 1339 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1340 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1341 } 1342 #endif 1343 1344 //============================================================================= 1345 1346 #ifndef PRODUCT 1347 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1348 Compile* C = ra_->C; 1349 const long framesize = C->frame_slots() << LogBytesPerInt; 1350 1351 st->print("PROLOG\n\t"); 1352 if (C->need_stack_bang(framesize)) { 1353 st->print("stack_overflow_check\n\t"); 1354 } 1355 1356 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1357 st->print("save return pc\n\t"); 1358 st->print("push frame %ld\n\t", -framesize); 1359 } 1360 } 1361 #endif 1362 1363 // Macro used instead of the common __ to emulate the pipes of PPC. 1364 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1365 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1366 // still no scheduling of this code is possible, the micro scheduler is aware of the 1367 // code and can update its internal data. The following mechanism is used to achieve this: 1368 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1369 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1370 #if 0 // TODO: PPC port 1371 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1372 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1373 _masm. 1374 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1375 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1376 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1377 C->hb_scheduling()->_pdScheduling->advance_offset 1378 #else 1379 #define ___(op) if (UsePower6SchedulerPPC64) \ 1380 Unimplemented(); \ 1381 _masm. 1382 #define ___stop if (UsePower6SchedulerPPC64) \ 1383 Unimplemented() 1384 #define ___advance if (UsePower6SchedulerPPC64) \ 1385 Unimplemented() 1386 #endif 1387 1388 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1389 Compile* C = ra_->C; 1390 MacroAssembler _masm(&cbuf); 1391 1392 const long framesize = C->frame_size_in_bytes(); 1393 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1394 1395 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1396 1397 const Register return_pc = R20; // Must match return_addr() in frame section. 1398 const Register callers_sp = R21; 1399 const Register push_frame_temp = R22; 1400 const Register toc_temp = R23; 1401 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1402 1403 if (method_is_frameless) { 1404 // Add nop at beginning of all frameless methods to prevent any 1405 // oop instructions from getting overwritten by make_not_entrant 1406 // (patching attempt would fail). 1407 ___(nop) nop(); 1408 } else { 1409 // Get return pc. 1410 ___(mflr) mflr(return_pc); 1411 } 1412 1413 // Calls to C2R adapters often do not accept exceptional returns. 1414 // We require that their callers must bang for them. But be 1415 // careful, because some VM calls (such as call site linkage) can 1416 // use several kilobytes of stack. But the stack safety zone should 1417 // account for that. See bugs 4446381, 4468289, 4497237. 1418 1419 int bangsize = C->bang_size_in_bytes(); 1420 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1421 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1422 // Unfortunately we cannot use the function provided in 1423 // assembler.cpp as we have to emulate the pipes. So I had to 1424 // insert the code of generate_stack_overflow_check(), see 1425 // assembler.cpp for some illuminative comments. 1426 const int page_size = os::vm_page_size(); 1427 int bang_end = JavaThread::stack_shadow_zone_size(); 1428 1429 // This is how far the previous frame's stack banging extended. 1430 const int bang_end_safe = bang_end; 1431 1432 if (bangsize > page_size) { 1433 bang_end += bangsize; 1434 } 1435 1436 int bang_offset = bang_end_safe; 1437 1438 while (bang_offset <= bang_end) { 1439 // Need at least one stack bang at end of shadow zone. 1440 1441 // Again I had to copy code, this time from assembler_ppc.cpp, 1442 // bang_stack_with_offset - see there for comments. 1443 1444 // Stack grows down, caller passes positive offset. 1445 assert(bang_offset > 0, "must bang with positive offset"); 1446 1447 long stdoffset = -bang_offset; 1448 1449 if (Assembler::is_simm(stdoffset, 16)) { 1450 // Signed 16 bit offset, a simple std is ok. 1451 if (UseLoadInstructionsForStackBangingPPC64) { 1452 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1453 } else { 1454 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1455 } 1456 } else if (Assembler::is_simm(stdoffset, 31)) { 1457 // Use largeoffset calculations for addis & ld/std. 1458 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1459 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1460 1461 Register tmp = R11; 1462 ___(addis) addis(tmp, R1_SP, hi); 1463 if (UseLoadInstructionsForStackBangingPPC64) { 1464 ___(ld) ld(R0, lo, tmp); 1465 } else { 1466 ___(std) std(R0, lo, tmp); 1467 } 1468 } else { 1469 ShouldNotReachHere(); 1470 } 1471 1472 bang_offset += page_size; 1473 } 1474 // R11 trashed 1475 } // C->need_stack_bang(framesize) && UseStackBanging 1476 1477 unsigned int bytes = (unsigned int)framesize; 1478 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1479 ciMethod *currMethod = C->method(); 1480 1481 // Optimized version for most common case. 1482 if (UsePower6SchedulerPPC64 && 1483 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1484 !(false /* ConstantsALot TODO: PPC port*/)) { 1485 ___(or) mr(callers_sp, R1_SP); 1486 ___(std) std(return_pc, _abi(lr), R1_SP); 1487 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1488 return; 1489 } 1490 1491 if (!method_is_frameless) { 1492 // Get callers sp. 1493 ___(or) mr(callers_sp, R1_SP); 1494 1495 // Push method's frame, modifies SP. 1496 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1497 // The ABI is already accounted for in 'framesize' via the 1498 // 'out_preserve' area. 1499 Register tmp = push_frame_temp; 1500 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1501 if (Assembler::is_simm(-offset, 16)) { 1502 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1503 } else { 1504 long x = -offset; 1505 // Had to insert load_const(tmp, -offset). 1506 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1507 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1508 ___(rldicr) sldi(tmp, tmp, 32); 1509 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1510 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1511 1512 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1513 } 1514 } 1515 #if 0 // TODO: PPC port 1516 // For testing large constant pools, emit a lot of constants to constant pool. 1517 // "Randomize" const_size. 1518 if (ConstantsALot) { 1519 const int num_consts = const_size(); 1520 for (int i = 0; i < num_consts; i++) { 1521 __ long_constant(0xB0B5B00BBABE); 1522 } 1523 } 1524 #endif 1525 if (!method_is_frameless) { 1526 // Save return pc. 1527 ___(std) std(return_pc, _abi(lr), callers_sp); 1528 } 1529 1530 C->set_frame_complete(cbuf.insts_size()); 1531 } 1532 #undef ___ 1533 #undef ___stop 1534 #undef ___advance 1535 1536 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1537 // Variable size. determine dynamically. 1538 return MachNode::size(ra_); 1539 } 1540 1541 int MachPrologNode::reloc() const { 1542 // Return number of relocatable values contained in this instruction. 1543 return 1; // 1 reloc entry for load_const(toc). 1544 } 1545 1546 //============================================================================= 1547 1548 #ifndef PRODUCT 1549 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1550 Compile* C = ra_->C; 1551 1552 st->print("EPILOG\n\t"); 1553 st->print("restore return pc\n\t"); 1554 st->print("pop frame\n\t"); 1555 1556 if (do_polling() && C->is_method_compilation()) { 1557 st->print("touch polling page\n\t"); 1558 } 1559 } 1560 #endif 1561 1562 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1563 Compile* C = ra_->C; 1564 MacroAssembler _masm(&cbuf); 1565 1566 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1567 assert(framesize >= 0, "negative frame-size?"); 1568 1569 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1570 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1571 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1572 const Register polling_page = R12; 1573 1574 if (!method_is_frameless) { 1575 // Restore return pc relative to callers' sp. 1576 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1577 } 1578 1579 if (method_needs_polling) { 1580 if (SafepointMechanism::uses_thread_local_poll()) { 1581 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1582 } else { 1583 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1584 } 1585 } 1586 1587 if (!method_is_frameless) { 1588 // Move return pc to LR. 1589 __ mtlr(return_pc); 1590 // Pop frame (fixed frame-size). 1591 __ addi(R1_SP, R1_SP, (int)framesize); 1592 } 1593 1594 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1595 __ reserved_stack_check(return_pc); 1596 } 1597 1598 if (method_needs_polling) { 1599 // We need to mark the code position where the load from the safepoint 1600 // polling page was emitted as relocInfo::poll_return_type here. 1601 __ relocate(relocInfo::poll_return_type); 1602 __ load_from_polling_page(polling_page); 1603 } 1604 } 1605 1606 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1607 // Variable size. Determine dynamically. 1608 return MachNode::size(ra_); 1609 } 1610 1611 int MachEpilogNode::reloc() const { 1612 // Return number of relocatable values contained in this instruction. 1613 return 1; // 1 for load_from_polling_page. 1614 } 1615 1616 const Pipeline * MachEpilogNode::pipeline() const { 1617 return MachNode::pipeline_class(); 1618 } 1619 1620 // This method seems to be obsolete. It is declared in machnode.hpp 1621 // and defined in all *.ad files, but it is never called. Should we 1622 // get rid of it? 1623 int MachEpilogNode::safepoint_offset() const { 1624 assert(do_polling(), "no return for this epilog node"); 1625 return 0; 1626 } 1627 1628 #if 0 // TODO: PPC port 1629 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1630 MacroAssembler _masm(&cbuf); 1631 if (LoadPollAddressFromThread) { 1632 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1633 } else { 1634 _masm.nop(); 1635 } 1636 } 1637 1638 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1639 if (LoadPollAddressFromThread) { 1640 return 4; 1641 } else { 1642 return 4; 1643 } 1644 } 1645 1646 #ifndef PRODUCT 1647 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1648 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1649 } 1650 #endif 1651 1652 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1653 return RSCRATCH1_BITS64_REG_mask(); 1654 } 1655 #endif // PPC port 1656 1657 // ============================================================================= 1658 1659 // Figure out which register class each belongs in: rc_int, rc_float or 1660 // rc_stack. 1661 enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1662 1663 static enum RC rc_class(OptoReg::Name reg) { 1664 // Return the register class for the given register. The given register 1665 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1666 // enumeration in adGlobals_ppc.hpp. 1667 1668 if (reg == OptoReg::Bad) return rc_bad; 1669 1670 // We have 64 integer register halves, starting at index 0. 1671 if (reg < 64) return rc_int; 1672 1673 // We have 64 floating-point register halves, starting at index 64. 1674 if (reg < 64+64) return rc_float; 1675 1676 // We have 64 vector-scalar registers, starting at index 128. 1677 if (reg < 64+64+64) return rc_vs; 1678 1679 // Between float regs & stack are the flags regs. 1680 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1681 1682 return rc_stack; 1683 } 1684 1685 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1686 bool do_print, Compile* C, outputStream *st) { 1687 1688 assert(opcode == Assembler::LD_OPCODE || 1689 opcode == Assembler::STD_OPCODE || 1690 opcode == Assembler::LWZ_OPCODE || 1691 opcode == Assembler::STW_OPCODE || 1692 opcode == Assembler::LFD_OPCODE || 1693 opcode == Assembler::STFD_OPCODE || 1694 opcode == Assembler::LFS_OPCODE || 1695 opcode == Assembler::STFS_OPCODE, 1696 "opcode not supported"); 1697 1698 if (cbuf) { 1699 int d = 1700 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1701 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1702 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1703 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1704 } 1705 #ifndef PRODUCT 1706 else if (do_print) { 1707 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1708 op_str, 1709 Matcher::regName[reg], 1710 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1711 } 1712 #endif 1713 return 4; // size 1714 } 1715 1716 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1717 Compile* C = ra_->C; 1718 1719 // Get registers to move. 1720 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1721 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1722 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1723 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1724 1725 enum RC src_hi_rc = rc_class(src_hi); 1726 enum RC src_lo_rc = rc_class(src_lo); 1727 enum RC dst_hi_rc = rc_class(dst_hi); 1728 enum RC dst_lo_rc = rc_class(dst_lo); 1729 1730 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1731 if (src_hi != OptoReg::Bad) 1732 assert((src_lo&1)==0 && src_lo+1==src_hi && 1733 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1734 "expected aligned-adjacent pairs"); 1735 // Generate spill code! 1736 int size = 0; 1737 1738 if (src_lo == dst_lo && src_hi == dst_hi) 1739 return size; // Self copy, no move. 1740 1741 if (bottom_type()->isa_vect() != NULL) { 1742 assert(src_lo_rc == rc_vs || dst_lo_rc == rc_vs, "expected at least src or dst is vector-scalar class"); 1743 assert(ideal_reg() == Op_VecX, "expected vector-scalar register class"); 1744 // Memory->Memory Spill. 1745 if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1746 int src_offset = ra_->reg2offset(src_lo); 1747 int dst_offset = ra_->reg2offset(dst_lo); 1748 if (cbuf) { 1749 MacroAssembler _masm(cbuf); 1750 __ ld(R0, src_offset, R1_SP); 1751 __ std(R0, dst_offset, R1_SP); 1752 __ ld(R0, src_offset+8, R1_SP); 1753 __ std(R0, dst_offset+8, R1_SP); 1754 } 1755 size += 16; 1756 } 1757 // VectorSRegister->Memory Spill. 1758 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1759 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1760 int dst_offset = ra_->reg2offset(dst_lo); 1761 if (cbuf) { 1762 MacroAssembler _masm(cbuf); 1763 __ addi(R0, R1_SP, dst_offset); 1764 __ stxvd2x(Rsrc, R0); 1765 } 1766 size += 8; 1767 } 1768 // Memory->VectorSRegister Spill. 1769 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 int src_offset = ra_->reg2offset(src_lo); 1772 if (cbuf) { 1773 MacroAssembler _masm(cbuf); 1774 __ addi(R0, R1_SP, src_offset); 1775 __ lxvd2x(Rdst, R0); 1776 } 1777 size += 8; 1778 } 1779 else { 1780 ShouldNotReachHere(); // No VSR spill. 1781 } 1782 return size; 1783 } 1784 1785 // -------------------------------------- 1786 // Memory->Memory Spill. Use R0 to hold the value. 1787 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1788 int src_offset = ra_->reg2offset(src_lo); 1789 int dst_offset = ra_->reg2offset(dst_lo); 1790 if (src_hi != OptoReg::Bad) { 1791 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1792 "expected same type of move for high parts"); 1793 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1794 if (!cbuf && !do_size) st->print("\n\t"); 1795 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1796 } else { 1797 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1798 if (!cbuf && !do_size) st->print("\n\t"); 1799 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1800 } 1801 return size; 1802 } 1803 1804 // -------------------------------------- 1805 // Check for float->int copy; requires a trip through memory. 1806 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1807 Unimplemented(); 1808 } 1809 1810 // -------------------------------------- 1811 // Check for integer reg-reg copy. 1812 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1813 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1814 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1815 size = (Rsrc != Rdst) ? 4 : 0; 1816 1817 if (cbuf) { 1818 MacroAssembler _masm(cbuf); 1819 if (size) { 1820 __ mr(Rdst, Rsrc); 1821 } 1822 } 1823 #ifndef PRODUCT 1824 else if (!do_size) { 1825 if (size) { 1826 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } else { 1828 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1829 } 1830 } 1831 #endif 1832 return size; 1833 } 1834 1835 // Check for integer store. 1836 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1837 int dst_offset = ra_->reg2offset(dst_lo); 1838 if (src_hi != OptoReg::Bad) { 1839 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1840 "expected same type of move for high parts"); 1841 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } else { 1843 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1844 } 1845 return size; 1846 } 1847 1848 // Check for integer load. 1849 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1850 int src_offset = ra_->reg2offset(src_lo); 1851 if (src_hi != OptoReg::Bad) { 1852 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1853 "expected same type of move for high parts"); 1854 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } else { 1856 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1857 } 1858 return size; 1859 } 1860 1861 // Check for float reg-reg copy. 1862 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1863 if (cbuf) { 1864 MacroAssembler _masm(cbuf); 1865 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1866 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1867 __ fmr(Rdst, Rsrc); 1868 } 1869 #ifndef PRODUCT 1870 else if (!do_size) { 1871 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1872 } 1873 #endif 1874 return 4; 1875 } 1876 1877 // Check for float store. 1878 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1879 int dst_offset = ra_->reg2offset(dst_lo); 1880 if (src_hi != OptoReg::Bad) { 1881 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1882 "expected same type of move for high parts"); 1883 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } else { 1885 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1886 } 1887 return size; 1888 } 1889 1890 // Check for float load. 1891 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1892 int src_offset = ra_->reg2offset(src_lo); 1893 if (src_hi != OptoReg::Bad) { 1894 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1895 "expected same type of move for high parts"); 1896 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } else { 1898 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1899 } 1900 return size; 1901 } 1902 1903 // -------------------------------------------------------------------- 1904 // Check for hi bits still needing moving. Only happens for misaligned 1905 // arguments to native calls. 1906 if (src_hi == dst_hi) 1907 return size; // Self copy; no move. 1908 1909 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1910 ShouldNotReachHere(); // Unimplemented 1911 return 0; 1912 } 1913 1914 #ifndef PRODUCT 1915 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1916 if (!ra_) 1917 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1918 else 1919 implementation(NULL, ra_, false, st); 1920 } 1921 #endif 1922 1923 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1924 implementation(&cbuf, ra_, false, NULL); 1925 } 1926 1927 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1928 return implementation(NULL, ra_, true, NULL); 1929 } 1930 1931 #if 0 // TODO: PPC port 1932 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1933 #ifndef PRODUCT 1934 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1935 #endif 1936 assert(ra_->node_regs_max_index() != 0, ""); 1937 1938 // Get registers to move. 1939 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1940 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1941 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1942 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1943 1944 enum RC src_lo_rc = rc_class(src_lo); 1945 enum RC dst_lo_rc = rc_class(dst_lo); 1946 1947 if (src_lo == dst_lo && src_hi == dst_hi) 1948 return ppc64Opcode_none; // Self copy, no move. 1949 1950 // -------------------------------------- 1951 // Memory->Memory Spill. Use R0 to hold the value. 1952 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1953 return ppc64Opcode_compound; 1954 } 1955 1956 // -------------------------------------- 1957 // Check for float->int copy; requires a trip through memory. 1958 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1959 Unimplemented(); 1960 } 1961 1962 // -------------------------------------- 1963 // Check for integer reg-reg copy. 1964 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1965 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1966 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1967 if (Rsrc == Rdst) { 1968 return ppc64Opcode_none; 1969 } else { 1970 return ppc64Opcode_or; 1971 } 1972 } 1973 1974 // Check for integer store. 1975 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1976 if (src_hi != OptoReg::Bad) { 1977 return ppc64Opcode_std; 1978 } else { 1979 return ppc64Opcode_stw; 1980 } 1981 } 1982 1983 // Check for integer load. 1984 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1985 if (src_hi != OptoReg::Bad) { 1986 return ppc64Opcode_ld; 1987 } else { 1988 return ppc64Opcode_lwz; 1989 } 1990 } 1991 1992 // Check for float reg-reg copy. 1993 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1994 return ppc64Opcode_fmr; 1995 } 1996 1997 // Check for float store. 1998 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1999 if (src_hi != OptoReg::Bad) { 2000 return ppc64Opcode_stfd; 2001 } else { 2002 return ppc64Opcode_stfs; 2003 } 2004 } 2005 2006 // Check for float load. 2007 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2008 if (src_hi != OptoReg::Bad) { 2009 return ppc64Opcode_lfd; 2010 } else { 2011 return ppc64Opcode_lfs; 2012 } 2013 } 2014 2015 // -------------------------------------------------------------------- 2016 // Check for hi bits still needing moving. Only happens for misaligned 2017 // arguments to native calls. 2018 if (src_hi == dst_hi) { 2019 return ppc64Opcode_none; // Self copy; no move. 2020 } 2021 2022 ShouldNotReachHere(); 2023 return ppc64Opcode_undefined; 2024 } 2025 #endif // PPC port 2026 2027 #ifndef PRODUCT 2028 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2029 st->print("NOP \t// %d nops to pad for loops.", _count); 2030 } 2031 #endif 2032 2033 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2034 MacroAssembler _masm(&cbuf); 2035 // _count contains the number of nops needed for padding. 2036 for (int i = 0; i < _count; i++) { 2037 __ nop(); 2038 } 2039 } 2040 2041 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2042 return _count * 4; 2043 } 2044 2045 #ifndef PRODUCT 2046 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2047 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2048 char reg_str[128]; 2049 ra_->dump_register(this, reg_str); 2050 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2051 } 2052 #endif 2053 2054 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2055 MacroAssembler _masm(&cbuf); 2056 2057 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2058 int reg = ra_->get_encode(this); 2059 2060 if (Assembler::is_simm(offset, 16)) { 2061 __ addi(as_Register(reg), R1, offset); 2062 } else { 2063 ShouldNotReachHere(); 2064 } 2065 } 2066 2067 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2068 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2069 return 4; 2070 } 2071 2072 #ifndef PRODUCT 2073 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2074 st->print_cr("---- MachUEPNode ----"); 2075 st->print_cr("..."); 2076 } 2077 #endif 2078 2079 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2080 // This is the unverified entry point. 2081 MacroAssembler _masm(&cbuf); 2082 2083 // Inline_cache contains a klass. 2084 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2085 Register receiver_klass = R12_scratch2; // tmp 2086 2087 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2088 assert(R11_scratch1 == R11, "need prologue scratch register"); 2089 2090 // Check for NULL argument if we don't have implicit null checks. 2091 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2092 if (TrapBasedNullChecks) { 2093 __ trap_null_check(R3_ARG1); 2094 } else { 2095 Label valid; 2096 __ cmpdi(CCR0, R3_ARG1, 0); 2097 __ bne_predict_taken(CCR0, valid); 2098 // We have a null argument, branch to ic_miss_stub. 2099 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2100 relocInfo::runtime_call_type); 2101 __ bind(valid); 2102 } 2103 } 2104 // Assume argument is not NULL, load klass from receiver. 2105 __ load_klass(receiver_klass, R3_ARG1); 2106 2107 if (TrapBasedICMissChecks) { 2108 __ trap_ic_miss_check(receiver_klass, ic_klass); 2109 } else { 2110 Label valid; 2111 __ cmpd(CCR0, receiver_klass, ic_klass); 2112 __ beq_predict_taken(CCR0, valid); 2113 // We have an unexpected klass, branch to ic_miss_stub. 2114 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2115 relocInfo::runtime_call_type); 2116 __ bind(valid); 2117 } 2118 2119 // Argument is valid and klass is as expected, continue. 2120 } 2121 2122 #if 0 // TODO: PPC port 2123 // Optimize UEP code on z (save a load_const() call in main path). 2124 int MachUEPNode::ep_offset() { 2125 return 0; 2126 } 2127 #endif 2128 2129 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2130 // Variable size. Determine dynamically. 2131 return MachNode::size(ra_); 2132 } 2133 2134 //============================================================================= 2135 2136 %} // interrupt source 2137 2138 source_hpp %{ // Header information of the source block. 2139 2140 class HandlerImpl { 2141 2142 public: 2143 2144 static int emit_exception_handler(CodeBuffer &cbuf); 2145 static int emit_deopt_handler(CodeBuffer& cbuf); 2146 2147 static uint size_exception_handler() { 2148 // The exception_handler is a b64_patchable. 2149 return MacroAssembler::b64_patchable_size; 2150 } 2151 2152 static uint size_deopt_handler() { 2153 // The deopt_handler is a bl64_patchable. 2154 return MacroAssembler::bl64_patchable_size; 2155 } 2156 2157 }; 2158 2159 %} // end source_hpp 2160 2161 source %{ 2162 2163 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2164 MacroAssembler _masm(&cbuf); 2165 2166 address base = __ start_a_stub(size_exception_handler()); 2167 if (base == NULL) return 0; // CodeBuffer::expand failed 2168 2169 int offset = __ offset(); 2170 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2171 relocInfo::runtime_call_type); 2172 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2173 __ end_a_stub(); 2174 2175 return offset; 2176 } 2177 2178 // The deopt_handler is like the exception handler, but it calls to 2179 // the deoptimization blob instead of jumping to the exception blob. 2180 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2181 MacroAssembler _masm(&cbuf); 2182 2183 address base = __ start_a_stub(size_deopt_handler()); 2184 if (base == NULL) return 0; // CodeBuffer::expand failed 2185 2186 int offset = __ offset(); 2187 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2188 relocInfo::runtime_call_type); 2189 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2190 __ end_a_stub(); 2191 2192 return offset; 2193 } 2194 2195 //============================================================================= 2196 2197 // Use a frame slots bias for frameless methods if accessing the stack. 2198 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2199 if (as_Register(reg_enc) == R1_SP) { 2200 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2201 } 2202 return 0; 2203 } 2204 2205 const bool Matcher::match_rule_supported(int opcode) { 2206 if (!has_match_rule(opcode)) 2207 return false; 2208 2209 switch (opcode) { 2210 case Op_SqrtD: 2211 return VM_Version::has_fsqrt(); 2212 case Op_CountLeadingZerosI: 2213 case Op_CountLeadingZerosL: 2214 case Op_CountTrailingZerosI: 2215 case Op_CountTrailingZerosL: 2216 if (!UseCountLeadingZerosInstructionsPPC64) 2217 return false; 2218 break; 2219 2220 case Op_PopCountI: 2221 case Op_PopCountL: 2222 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2223 2224 case Op_StrComp: 2225 return SpecialStringCompareTo; 2226 case Op_StrEquals: 2227 return SpecialStringEquals; 2228 case Op_StrIndexOf: 2229 return SpecialStringIndexOf; 2230 case Op_StrIndexOfChar: 2231 return SpecialStringIndexOf; 2232 } 2233 2234 return true; // Per default match rules are supported. 2235 } 2236 2237 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2238 2239 // TODO 2240 // identify extra cases that we might want to provide match rules for 2241 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2242 bool ret_value = match_rule_supported(opcode); 2243 // Add rules here. 2244 2245 return ret_value; // Per default match rules are supported. 2246 } 2247 2248 const bool Matcher::has_predicated_vectors(void) { 2249 return false; 2250 } 2251 2252 const int Matcher::float_pressure(int default_pressure_threshold) { 2253 return default_pressure_threshold; 2254 } 2255 2256 int Matcher::regnum_to_fpu_offset(int regnum) { 2257 // No user for this method? 2258 Unimplemented(); 2259 return 999; 2260 } 2261 2262 const bool Matcher::convL2FSupported(void) { 2263 // fcfids can do the conversion (>= Power7). 2264 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2265 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2266 } 2267 2268 // Vector width in bytes. 2269 const int Matcher::vector_width_in_bytes(BasicType bt) { 2270 if (SuperwordUseVSX) { 2271 assert(MaxVectorSize == 16, ""); 2272 return 16; 2273 } else { 2274 assert(MaxVectorSize == 8, ""); 2275 return 8; 2276 } 2277 } 2278 2279 // Vector ideal reg. 2280 const uint Matcher::vector_ideal_reg(int size) { 2281 if (SuperwordUseVSX) { 2282 assert(MaxVectorSize == 16 && size == 16, ""); 2283 return Op_VecX; 2284 } else { 2285 assert(MaxVectorSize == 8 && size == 8, ""); 2286 return Op_RegL; 2287 } 2288 } 2289 2290 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2291 fatal("vector shift is not supported"); 2292 return Node::NotAMachineReg; 2293 } 2294 2295 // Limits on vector size (number of elements) loaded into vector. 2296 const int Matcher::max_vector_size(const BasicType bt) { 2297 assert(is_java_primitive(bt), "only primitive type vectors"); 2298 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2299 } 2300 2301 const int Matcher::min_vector_size(const BasicType bt) { 2302 return max_vector_size(bt); // Same as max. 2303 } 2304 2305 // PPC doesn't support misaligned vectors store/load. 2306 const bool Matcher::misaligned_vectors_ok() { 2307 return !AlignVector; // can be changed by flag 2308 } 2309 2310 // PPC AES support not yet implemented 2311 const bool Matcher::pass_original_key_for_aes() { 2312 return false; 2313 } 2314 2315 // RETURNS: whether this branch offset is short enough that a short 2316 // branch can be used. 2317 // 2318 // If the platform does not provide any short branch variants, then 2319 // this method should return `false' for offset 0. 2320 // 2321 // `Compile::Fill_buffer' will decide on basis of this information 2322 // whether to do the pass `Compile::Shorten_branches' at all. 2323 // 2324 // And `Compile::Shorten_branches' will decide on basis of this 2325 // information whether to replace particular branch sites by short 2326 // ones. 2327 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2328 // Is the offset within the range of a ppc64 pc relative branch? 2329 bool b; 2330 2331 const int safety_zone = 3 * BytesPerInstWord; 2332 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2333 29 - 16 + 1 + 2); 2334 return b; 2335 } 2336 2337 const bool Matcher::isSimpleConstant64(jlong value) { 2338 // Probably always true, even if a temp register is required. 2339 return true; 2340 } 2341 /* TODO: PPC port 2342 // Make a new machine dependent decode node (with its operands). 2343 MachTypeNode *Matcher::make_decode_node() { 2344 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2345 "This method is only implemented for unscaled cOops mode so far"); 2346 MachTypeNode *decode = new decodeN_unscaledNode(); 2347 decode->set_opnd_array(0, new iRegPdstOper()); 2348 decode->set_opnd_array(1, new iRegNsrcOper()); 2349 return decode; 2350 } 2351 */ 2352 2353 // false => size gets scaled to BytesPerLong, ok. 2354 const bool Matcher::init_array_count_is_in_bytes = false; 2355 2356 // Use conditional move (CMOVL) on Power7. 2357 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2358 2359 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2360 // fsel doesn't accept a condition register as input, so this would be slightly different. 2361 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2362 2363 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2364 const bool Matcher::require_postalloc_expand = true; 2365 2366 // Do we need to mask the count passed to shift instructions or does 2367 // the cpu only look at the lower 5/6 bits anyway? 2368 // PowerPC requires masked shift counts. 2369 const bool Matcher::need_masked_shift_count = true; 2370 2371 // This affects two different things: 2372 // - how Decode nodes are matched 2373 // - how ImplicitNullCheck opportunities are recognized 2374 // If true, the matcher will try to remove all Decodes and match them 2375 // (as operands) into nodes. NullChecks are not prepared to deal with 2376 // Decodes by final_graph_reshaping(). 2377 // If false, final_graph_reshaping() forces the decode behind the Cmp 2378 // for a NullCheck. The matcher matches the Decode node into a register. 2379 // Implicit_null_check optimization moves the Decode along with the 2380 // memory operation back up before the NullCheck. 2381 bool Matcher::narrow_oop_use_complex_address() { 2382 // TODO: PPC port if (MatchDecodeNodes) return true; 2383 return false; 2384 } 2385 2386 bool Matcher::narrow_klass_use_complex_address() { 2387 NOT_LP64(ShouldNotCallThis()); 2388 assert(UseCompressedClassPointers, "only for compressed klass code"); 2389 // TODO: PPC port if (MatchDecodeNodes) return true; 2390 return false; 2391 } 2392 2393 bool Matcher::const_oop_prefer_decode() { 2394 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2395 return Universe::narrow_oop_base() == NULL; 2396 } 2397 2398 bool Matcher::const_klass_prefer_decode() { 2399 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2400 return Universe::narrow_klass_base() == NULL; 2401 } 2402 2403 // Is it better to copy float constants, or load them directly from memory? 2404 // Intel can load a float constant from a direct address, requiring no 2405 // extra registers. Most RISCs will have to materialize an address into a 2406 // register first, so they would do better to copy the constant from stack. 2407 const bool Matcher::rematerialize_float_constants = false; 2408 2409 // If CPU can load and store mis-aligned doubles directly then no fixup is 2410 // needed. Else we split the double into 2 integer pieces and move it 2411 // piece-by-piece. Only happens when passing doubles into C code as the 2412 // Java calling convention forces doubles to be aligned. 2413 const bool Matcher::misaligned_doubles_ok = true; 2414 2415 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2416 Unimplemented(); 2417 } 2418 2419 // Advertise here if the CPU requires explicit rounding operations 2420 // to implement the UseStrictFP mode. 2421 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2422 2423 // Do floats take an entire double register or just half? 2424 // 2425 // A float occupies a ppc64 double register. For the allocator, a 2426 // ppc64 double register appears as a pair of float registers. 2427 bool Matcher::float_in_double() { return true; } 2428 2429 // Do ints take an entire long register or just half? 2430 // The relevant question is how the int is callee-saved: 2431 // the whole long is written but de-opt'ing will have to extract 2432 // the relevant 32 bits. 2433 const bool Matcher::int_in_long = true; 2434 2435 // Constants for c2c and c calling conventions. 2436 2437 const MachRegisterNumbers iarg_reg[8] = { 2438 R3_num, R4_num, R5_num, R6_num, 2439 R7_num, R8_num, R9_num, R10_num 2440 }; 2441 2442 const MachRegisterNumbers farg_reg[13] = { 2443 F1_num, F2_num, F3_num, F4_num, 2444 F5_num, F6_num, F7_num, F8_num, 2445 F9_num, F10_num, F11_num, F12_num, 2446 F13_num 2447 }; 2448 2449 const MachRegisterNumbers vsarg_reg[64] = { 2450 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2451 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2452 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2453 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2454 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2455 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2456 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2457 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2458 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2459 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2460 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2461 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2462 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2463 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2464 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2465 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2466 }; 2467 2468 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2469 2470 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2471 2472 const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2473 2474 // Return whether or not this register is ever used as an argument. This 2475 // function is used on startup to build the trampoline stubs in generateOptoStub. 2476 // Registers not mentioned will be killed by the VM call in the trampoline, and 2477 // arguments in those registers not be available to the callee. 2478 bool Matcher::can_be_java_arg(int reg) { 2479 // We return true for all registers contained in iarg_reg[] and 2480 // farg_reg[] and their virtual halves. 2481 // We must include the virtual halves in order to get STDs and LDs 2482 // instead of STWs and LWs in the trampoline stubs. 2483 2484 if ( reg == R3_num || reg == R3_H_num 2485 || reg == R4_num || reg == R4_H_num 2486 || reg == R5_num || reg == R5_H_num 2487 || reg == R6_num || reg == R6_H_num 2488 || reg == R7_num || reg == R7_H_num 2489 || reg == R8_num || reg == R8_H_num 2490 || reg == R9_num || reg == R9_H_num 2491 || reg == R10_num || reg == R10_H_num) 2492 return true; 2493 2494 if ( reg == F1_num || reg == F1_H_num 2495 || reg == F2_num || reg == F2_H_num 2496 || reg == F3_num || reg == F3_H_num 2497 || reg == F4_num || reg == F4_H_num 2498 || reg == F5_num || reg == F5_H_num 2499 || reg == F6_num || reg == F6_H_num 2500 || reg == F7_num || reg == F7_H_num 2501 || reg == F8_num || reg == F8_H_num 2502 || reg == F9_num || reg == F9_H_num 2503 || reg == F10_num || reg == F10_H_num 2504 || reg == F11_num || reg == F11_H_num 2505 || reg == F12_num || reg == F12_H_num 2506 || reg == F13_num || reg == F13_H_num) 2507 return true; 2508 2509 return false; 2510 } 2511 2512 bool Matcher::is_spillable_arg(int reg) { 2513 return can_be_java_arg(reg); 2514 } 2515 2516 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2517 return false; 2518 } 2519 2520 // Register for DIVI projection of divmodI. 2521 RegMask Matcher::divI_proj_mask() { 2522 ShouldNotReachHere(); 2523 return RegMask(); 2524 } 2525 2526 // Register for MODI projection of divmodI. 2527 RegMask Matcher::modI_proj_mask() { 2528 ShouldNotReachHere(); 2529 return RegMask(); 2530 } 2531 2532 // Register for DIVL projection of divmodL. 2533 RegMask Matcher::divL_proj_mask() { 2534 ShouldNotReachHere(); 2535 return RegMask(); 2536 } 2537 2538 // Register for MODL projection of divmodL. 2539 RegMask Matcher::modL_proj_mask() { 2540 ShouldNotReachHere(); 2541 return RegMask(); 2542 } 2543 2544 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2545 return RegMask(); 2546 } 2547 2548 const bool Matcher::convi2l_type_required = true; 2549 2550 %} 2551 2552 //----------ENCODING BLOCK----------------------------------------------------- 2553 // This block specifies the encoding classes used by the compiler to output 2554 // byte streams. Encoding classes are parameterized macros used by 2555 // Machine Instruction Nodes in order to generate the bit encoding of the 2556 // instruction. Operands specify their base encoding interface with the 2557 // interface keyword. There are currently supported four interfaces, 2558 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2559 // operand to generate a function which returns its register number when 2560 // queried. CONST_INTER causes an operand to generate a function which 2561 // returns the value of the constant when queried. MEMORY_INTER causes an 2562 // operand to generate four functions which return the Base Register, the 2563 // Index Register, the Scale Value, and the Offset Value of the operand when 2564 // queried. COND_INTER causes an operand to generate six functions which 2565 // return the encoding code (ie - encoding bits for the instruction) 2566 // associated with each basic boolean condition for a conditional instruction. 2567 // 2568 // Instructions specify two basic values for encoding. Again, a function 2569 // is available to check if the constant displacement is an oop. They use the 2570 // ins_encode keyword to specify their encoding classes (which must be 2571 // a sequence of enc_class names, and their parameters, specified in 2572 // the encoding block), and they use the 2573 // opcode keyword to specify, in order, their primary, secondary, and 2574 // tertiary opcode. Only the opcode sections which a particular instruction 2575 // needs for encoding need to be specified. 2576 encode %{ 2577 enc_class enc_unimplemented %{ 2578 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2579 MacroAssembler _masm(&cbuf); 2580 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2581 %} 2582 2583 enc_class enc_untested %{ 2584 #ifdef ASSERT 2585 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2586 MacroAssembler _masm(&cbuf); 2587 __ untested("Untested mach node encoding in AD file."); 2588 #else 2589 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2590 #endif 2591 %} 2592 2593 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2594 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2595 MacroAssembler _masm(&cbuf); 2596 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2597 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2598 %} 2599 2600 // Load acquire. 2601 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2603 MacroAssembler _masm(&cbuf); 2604 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2605 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2606 __ twi_0($dst$$Register); 2607 __ isync(); 2608 %} 2609 2610 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2611 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2612 2613 MacroAssembler _masm(&cbuf); 2614 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2615 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2616 %} 2617 2618 // Load acquire. 2619 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2620 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2621 2622 MacroAssembler _masm(&cbuf); 2623 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2624 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2625 __ twi_0($dst$$Register); 2626 __ isync(); 2627 %} 2628 2629 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2630 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2631 2632 MacroAssembler _masm(&cbuf); 2633 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2634 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2635 %} 2636 2637 // Load acquire. 2638 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2639 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2640 2641 MacroAssembler _masm(&cbuf); 2642 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2643 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2644 __ twi_0($dst$$Register); 2645 __ isync(); 2646 %} 2647 2648 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2649 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2650 MacroAssembler _masm(&cbuf); 2651 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2652 // Operand 'ds' requires 4-alignment. 2653 assert((Idisp & 0x3) == 0, "unaligned offset"); 2654 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2655 %} 2656 2657 // Load acquire. 2658 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2659 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2660 MacroAssembler _masm(&cbuf); 2661 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2662 // Operand 'ds' requires 4-alignment. 2663 assert((Idisp & 0x3) == 0, "unaligned offset"); 2664 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2665 __ twi_0($dst$$Register); 2666 __ isync(); 2667 %} 2668 2669 enc_class enc_lfd(RegF dst, memory mem) %{ 2670 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2671 MacroAssembler _masm(&cbuf); 2672 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2673 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2674 %} 2675 2676 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2677 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2678 2679 MacroAssembler _masm(&cbuf); 2680 int toc_offset = 0; 2681 2682 address const_toc_addr; 2683 // Create a non-oop constant, no relocation needed. 2684 // If it is an IC, it has a virtual_call_Relocation. 2685 const_toc_addr = __ long_constant((jlong)$src$$constant); 2686 if (const_toc_addr == NULL) { 2687 ciEnv::current()->record_out_of_memory_failure(); 2688 return; 2689 } 2690 2691 // Get the constant's TOC offset. 2692 toc_offset = __ offset_to_method_toc(const_toc_addr); 2693 2694 // Keep the current instruction offset in mind. 2695 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2696 2697 __ ld($dst$$Register, toc_offset, $toc$$Register); 2698 %} 2699 2700 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2701 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2702 2703 MacroAssembler _masm(&cbuf); 2704 2705 if (!ra_->C->in_scratch_emit_size()) { 2706 address const_toc_addr; 2707 // Create a non-oop constant, no relocation needed. 2708 // If it is an IC, it has a virtual_call_Relocation. 2709 const_toc_addr = __ long_constant((jlong)$src$$constant); 2710 if (const_toc_addr == NULL) { 2711 ciEnv::current()->record_out_of_memory_failure(); 2712 return; 2713 } 2714 2715 // Get the constant's TOC offset. 2716 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2717 // Store the toc offset of the constant. 2718 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2719 2720 // Also keep the current instruction offset in mind. 2721 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2722 } 2723 2724 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2725 %} 2726 2727 %} // encode 2728 2729 source %{ 2730 2731 typedef struct { 2732 loadConL_hiNode *_large_hi; 2733 loadConL_loNode *_large_lo; 2734 loadConLNode *_small; 2735 MachNode *_last; 2736 } loadConLNodesTuple; 2737 2738 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2739 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2740 loadConLNodesTuple nodes; 2741 2742 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2743 if (large_constant_pool) { 2744 // Create new nodes. 2745 loadConL_hiNode *m1 = new loadConL_hiNode(); 2746 loadConL_loNode *m2 = new loadConL_loNode(); 2747 2748 // inputs for new nodes 2749 m1->add_req(NULL, toc); 2750 m2->add_req(NULL, m1); 2751 2752 // operands for new nodes 2753 m1->_opnds[0] = new iRegLdstOper(); // dst 2754 m1->_opnds[1] = immSrc; // src 2755 m1->_opnds[2] = new iRegPdstOper(); // toc 2756 m2->_opnds[0] = new iRegLdstOper(); // dst 2757 m2->_opnds[1] = immSrc; // src 2758 m2->_opnds[2] = new iRegLdstOper(); // base 2759 2760 // Initialize ins_attrib TOC fields. 2761 m1->_const_toc_offset = -1; 2762 m2->_const_toc_offset_hi_node = m1; 2763 2764 // Initialize ins_attrib instruction offset. 2765 m1->_cbuf_insts_offset = -1; 2766 2767 // register allocation for new nodes 2768 ra_->set_pair(m1->_idx, reg_second, reg_first); 2769 ra_->set_pair(m2->_idx, reg_second, reg_first); 2770 2771 // Create result. 2772 nodes._large_hi = m1; 2773 nodes._large_lo = m2; 2774 nodes._small = NULL; 2775 nodes._last = nodes._large_lo; 2776 assert(m2->bottom_type()->isa_long(), "must be long"); 2777 } else { 2778 loadConLNode *m2 = new loadConLNode(); 2779 2780 // inputs for new nodes 2781 m2->add_req(NULL, toc); 2782 2783 // operands for new nodes 2784 m2->_opnds[0] = new iRegLdstOper(); // dst 2785 m2->_opnds[1] = immSrc; // src 2786 m2->_opnds[2] = new iRegPdstOper(); // toc 2787 2788 // Initialize ins_attrib instruction offset. 2789 m2->_cbuf_insts_offset = -1; 2790 2791 // register allocation for new nodes 2792 ra_->set_pair(m2->_idx, reg_second, reg_first); 2793 2794 // Create result. 2795 nodes._large_hi = NULL; 2796 nodes._large_lo = NULL; 2797 nodes._small = m2; 2798 nodes._last = nodes._small; 2799 assert(m2->bottom_type()->isa_long(), "must be long"); 2800 } 2801 2802 return nodes; 2803 } 2804 2805 typedef struct { 2806 loadConL_hiNode *_large_hi; 2807 loadConL_loNode *_large_lo; 2808 mtvsrdNode *_moved; 2809 xxspltdNode *_replicated; 2810 loadConLNode *_small; 2811 MachNode *_last; 2812 } loadConLReplicatedNodesTuple; 2813 2814 loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2815 vecXOper *dst, immI_0Oper *zero, 2816 OptoReg::Name reg_second, OptoReg::Name reg_first, 2817 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2818 loadConLReplicatedNodesTuple nodes; 2819 2820 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2821 if (large_constant_pool) { 2822 // Create new nodes. 2823 loadConL_hiNode *m1 = new loadConL_hiNode(); 2824 loadConL_loNode *m2 = new loadConL_loNode(); 2825 mtvsrdNode *m3 = new mtvsrdNode(); 2826 xxspltdNode *m4 = new xxspltdNode(); 2827 2828 // inputs for new nodes 2829 m1->add_req(NULL, toc); 2830 m2->add_req(NULL, m1); 2831 m3->add_req(NULL, m2); 2832 m4->add_req(NULL, m3); 2833 2834 // operands for new nodes 2835 m1->_opnds[0] = new iRegLdstOper(); // dst 2836 m1->_opnds[1] = immSrc; // src 2837 m1->_opnds[2] = new iRegPdstOper(); // toc 2838 2839 m2->_opnds[0] = new iRegLdstOper(); // dst 2840 m2->_opnds[1] = immSrc; // src 2841 m2->_opnds[2] = new iRegLdstOper(); // base 2842 2843 m3->_opnds[0] = new vecXOper(); // dst 2844 m3->_opnds[1] = new iRegLdstOper(); // src 2845 2846 m4->_opnds[0] = new vecXOper(); // dst 2847 m4->_opnds[1] = new vecXOper(); // src 2848 m4->_opnds[2] = zero; 2849 2850 // Initialize ins_attrib TOC fields. 2851 m1->_const_toc_offset = -1; 2852 m2->_const_toc_offset_hi_node = m1; 2853 2854 // Initialize ins_attrib instruction offset. 2855 m1->_cbuf_insts_offset = -1; 2856 2857 // register allocation for new nodes 2858 ra_->set_pair(m1->_idx, reg_second, reg_first); 2859 ra_->set_pair(m2->_idx, reg_second, reg_first); 2860 ra_->set1(m3->_idx, reg_second); 2861 ra_->set2(m3->_idx, reg_vec_first); 2862 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2863 2864 // Create result. 2865 nodes._large_hi = m1; 2866 nodes._large_lo = m2; 2867 nodes._moved = m3; 2868 nodes._replicated = m4; 2869 nodes._small = NULL; 2870 nodes._last = nodes._replicated; 2871 assert(m2->bottom_type()->isa_long(), "must be long"); 2872 } else { 2873 loadConLNode *m2 = new loadConLNode(); 2874 mtvsrdNode *m3 = new mtvsrdNode(); 2875 xxspltdNode *m4 = new xxspltdNode(); 2876 2877 // inputs for new nodes 2878 m2->add_req(NULL, toc); 2879 2880 // operands for new nodes 2881 m2->_opnds[0] = new iRegLdstOper(); // dst 2882 m2->_opnds[1] = immSrc; // src 2883 m2->_opnds[2] = new iRegPdstOper(); // toc 2884 2885 m3->_opnds[0] = new vecXOper(); // dst 2886 m3->_opnds[1] = new iRegLdstOper(); // src 2887 2888 m4->_opnds[0] = new vecXOper(); // dst 2889 m4->_opnds[1] = new vecXOper(); // src 2890 m4->_opnds[2] = zero; 2891 2892 // Initialize ins_attrib instruction offset. 2893 m2->_cbuf_insts_offset = -1; 2894 ra_->set1(m3->_idx, reg_second); 2895 ra_->set2(m3->_idx, reg_vec_first); 2896 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2897 2898 // register allocation for new nodes 2899 ra_->set_pair(m2->_idx, reg_second, reg_first); 2900 2901 // Create result. 2902 nodes._large_hi = NULL; 2903 nodes._large_lo = NULL; 2904 nodes._small = m2; 2905 nodes._moved = m3; 2906 nodes._replicated = m4; 2907 nodes._last = nodes._replicated; 2908 assert(m2->bottom_type()->isa_long(), "must be long"); 2909 } 2910 2911 return nodes; 2912 } 2913 2914 %} // source 2915 2916 encode %{ 2917 // Postalloc expand emitter for loading a long constant from the method's TOC. 2918 // Enc_class needed as consttanttablebase is not supported by postalloc 2919 // expand. 2920 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2921 // Create new nodes. 2922 loadConLNodesTuple loadConLNodes = 2923 loadConLNodesTuple_create(ra_, n_toc, op_src, 2924 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2925 2926 // Push new nodes. 2927 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2928 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2929 2930 // some asserts 2931 assert(nodes->length() >= 1, "must have created at least 1 node"); 2932 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2933 %} 2934 2935 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2936 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2937 2938 MacroAssembler _masm(&cbuf); 2939 int toc_offset = 0; 2940 2941 intptr_t val = $src$$constant; 2942 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2943 address const_toc_addr; 2944 if (constant_reloc == relocInfo::oop_type) { 2945 // Create an oop constant and a corresponding relocation. 2946 AddressLiteral a = __ allocate_oop_address((jobject)val); 2947 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2948 __ relocate(a.rspec()); 2949 } else if (constant_reloc == relocInfo::metadata_type) { 2950 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2951 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2952 __ relocate(a.rspec()); 2953 } else { 2954 // Create a non-oop constant, no relocation needed. 2955 const_toc_addr = __ long_constant((jlong)$src$$constant); 2956 } 2957 2958 if (const_toc_addr == NULL) { 2959 ciEnv::current()->record_out_of_memory_failure(); 2960 return; 2961 } 2962 // Get the constant's TOC offset. 2963 toc_offset = __ offset_to_method_toc(const_toc_addr); 2964 2965 __ ld($dst$$Register, toc_offset, $toc$$Register); 2966 %} 2967 2968 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2969 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2970 2971 MacroAssembler _masm(&cbuf); 2972 if (!ra_->C->in_scratch_emit_size()) { 2973 intptr_t val = $src$$constant; 2974 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2975 address const_toc_addr; 2976 if (constant_reloc == relocInfo::oop_type) { 2977 // Create an oop constant and a corresponding relocation. 2978 AddressLiteral a = __ allocate_oop_address((jobject)val); 2979 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2980 __ relocate(a.rspec()); 2981 } else if (constant_reloc == relocInfo::metadata_type) { 2982 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2983 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2984 __ relocate(a.rspec()); 2985 } else { // non-oop pointers, e.g. card mark base, heap top 2986 // Create a non-oop constant, no relocation needed. 2987 const_toc_addr = __ long_constant((jlong)$src$$constant); 2988 } 2989 2990 if (const_toc_addr == NULL) { 2991 ciEnv::current()->record_out_of_memory_failure(); 2992 return; 2993 } 2994 // Get the constant's TOC offset. 2995 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2996 // Store the toc offset of the constant. 2997 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2998 } 2999 3000 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3001 %} 3002 3003 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3004 // Enc_class needed as consttanttablebase is not supported by postalloc 3005 // expand. 3006 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3007 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3008 if (large_constant_pool) { 3009 // Create new nodes. 3010 loadConP_hiNode *m1 = new loadConP_hiNode(); 3011 loadConP_loNode *m2 = new loadConP_loNode(); 3012 3013 // inputs for new nodes 3014 m1->add_req(NULL, n_toc); 3015 m2->add_req(NULL, m1); 3016 3017 // operands for new nodes 3018 m1->_opnds[0] = new iRegPdstOper(); // dst 3019 m1->_opnds[1] = op_src; // src 3020 m1->_opnds[2] = new iRegPdstOper(); // toc 3021 m2->_opnds[0] = new iRegPdstOper(); // dst 3022 m2->_opnds[1] = op_src; // src 3023 m2->_opnds[2] = new iRegLdstOper(); // base 3024 3025 // Initialize ins_attrib TOC fields. 3026 m1->_const_toc_offset = -1; 3027 m2->_const_toc_offset_hi_node = m1; 3028 3029 // Register allocation for new nodes. 3030 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3031 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3032 3033 nodes->push(m1); 3034 nodes->push(m2); 3035 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3036 } else { 3037 loadConPNode *m2 = new loadConPNode(); 3038 3039 // inputs for new nodes 3040 m2->add_req(NULL, n_toc); 3041 3042 // operands for new nodes 3043 m2->_opnds[0] = new iRegPdstOper(); // dst 3044 m2->_opnds[1] = op_src; // src 3045 m2->_opnds[2] = new iRegPdstOper(); // toc 3046 3047 // Register allocation for new nodes. 3048 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3049 3050 nodes->push(m2); 3051 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3052 } 3053 %} 3054 3055 // Enc_class needed as consttanttablebase is not supported by postalloc 3056 // expand. 3057 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3058 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3059 3060 MachNode *m2; 3061 if (large_constant_pool) { 3062 m2 = new loadConFCompNode(); 3063 } else { 3064 m2 = new loadConFNode(); 3065 } 3066 // inputs for new nodes 3067 m2->add_req(NULL, n_toc); 3068 3069 // operands for new nodes 3070 m2->_opnds[0] = op_dst; 3071 m2->_opnds[1] = op_src; 3072 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3073 3074 // register allocation for new nodes 3075 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3076 nodes->push(m2); 3077 %} 3078 3079 // Enc_class needed as consttanttablebase is not supported by postalloc 3080 // expand. 3081 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3082 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3083 3084 MachNode *m2; 3085 if (large_constant_pool) { 3086 m2 = new loadConDCompNode(); 3087 } else { 3088 m2 = new loadConDNode(); 3089 } 3090 // inputs for new nodes 3091 m2->add_req(NULL, n_toc); 3092 3093 // operands for new nodes 3094 m2->_opnds[0] = op_dst; 3095 m2->_opnds[1] = op_src; 3096 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3097 3098 // register allocation for new nodes 3099 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3100 nodes->push(m2); 3101 %} 3102 3103 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3104 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3105 MacroAssembler _masm(&cbuf); 3106 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3107 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3108 %} 3109 3110 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3111 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3112 MacroAssembler _masm(&cbuf); 3113 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3114 // Operand 'ds' requires 4-alignment. 3115 assert((Idisp & 0x3) == 0, "unaligned offset"); 3116 __ std($src$$Register, Idisp, $mem$$base$$Register); 3117 %} 3118 3119 enc_class enc_stfs(RegF src, memory mem) %{ 3120 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3121 MacroAssembler _masm(&cbuf); 3122 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3123 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3124 %} 3125 3126 enc_class enc_stfd(RegF src, memory mem) %{ 3127 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3128 MacroAssembler _masm(&cbuf); 3129 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3130 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3131 %} 3132 3133 // Use release_store for card-marking to ensure that previous 3134 // oop-stores are visible before the card-mark change. 3135 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3136 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3137 // FIXME: Implement this as a cmove and use a fixed condition code 3138 // register which is written on every transition to compiled code, 3139 // e.g. in call-stub and when returning from runtime stubs. 3140 // 3141 // Proposed code sequence for the cmove implementation: 3142 // 3143 // Label skip_release; 3144 // __ beq(CCRfixed, skip_release); 3145 // __ release(); 3146 // __ bind(skip_release); 3147 // __ stb(card mark); 3148 3149 MacroAssembler _masm(&cbuf); 3150 Label skip_storestore; 3151 3152 #if 0 // TODO: PPC port 3153 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 3154 // StoreStore barrier conditionally. 3155 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3156 __ cmpwi($crx$$CondRegister, R0, 0); 3157 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3158 #endif 3159 __ li(R0, 0); 3160 __ membar(Assembler::StoreStore); 3161 #if 0 // TODO: PPC port 3162 __ bind(skip_storestore); 3163 #endif 3164 3165 // Do the store. 3166 if ($mem$$index == 0) { 3167 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3168 } else { 3169 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3170 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3171 } 3172 %} 3173 3174 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3175 3176 if (VM_Version::has_isel()) { 3177 // use isel instruction with Power 7 3178 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3179 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3180 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3181 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3182 3183 n_compare->add_req(n_region, n_src); 3184 n_compare->_opnds[0] = op_crx; 3185 n_compare->_opnds[1] = op_src; 3186 n_compare->_opnds[2] = new immL16Oper(0); 3187 3188 n_sub_base->add_req(n_region, n_src); 3189 n_sub_base->_opnds[0] = op_dst; 3190 n_sub_base->_opnds[1] = 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 n_cond_set->add_req(n_region, n_compare, n_shift); 3199 n_cond_set->_opnds[0] = op_dst; 3200 n_cond_set->_opnds[1] = op_crx; 3201 n_cond_set->_opnds[2] = op_dst; 3202 n_cond_set->_bottom_type = _bottom_type; 3203 3204 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3205 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3206 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3207 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3208 3209 nodes->push(n_compare); 3210 nodes->push(n_sub_base); 3211 nodes->push(n_shift); 3212 nodes->push(n_cond_set); 3213 3214 } else { 3215 // before Power 7 3216 moveRegNode *n_move = new moveRegNode(); 3217 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3218 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3219 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3220 3221 n_move->add_req(n_region, n_src); 3222 n_move->_opnds[0] = op_dst; 3223 n_move->_opnds[1] = op_src; 3224 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3225 3226 n_compare->add_req(n_region, n_src); 3227 n_compare->add_prec(n_move); 3228 3229 n_compare->_opnds[0] = op_crx; 3230 n_compare->_opnds[1] = op_src; 3231 n_compare->_opnds[2] = new immL16Oper(0); 3232 3233 n_sub_base->add_req(n_region, n_compare, n_src); 3234 n_sub_base->_opnds[0] = op_dst; 3235 n_sub_base->_opnds[1] = op_crx; 3236 n_sub_base->_opnds[2] = op_src; 3237 n_sub_base->_bottom_type = _bottom_type; 3238 3239 n_shift->add_req(n_region, n_sub_base); 3240 n_shift->_opnds[0] = op_dst; 3241 n_shift->_opnds[1] = op_dst; 3242 n_shift->_bottom_type = _bottom_type; 3243 3244 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3245 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3246 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3247 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3248 3249 nodes->push(n_move); 3250 nodes->push(n_compare); 3251 nodes->push(n_sub_base); 3252 nodes->push(n_shift); 3253 } 3254 3255 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3256 %} 3257 3258 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3259 3260 encodeP_subNode *n1 = new encodeP_subNode(); 3261 n1->add_req(n_region, n_src); 3262 n1->_opnds[0] = op_dst; 3263 n1->_opnds[1] = op_src; 3264 n1->_bottom_type = _bottom_type; 3265 3266 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3267 n2->add_req(n_region, n1); 3268 n2->_opnds[0] = op_dst; 3269 n2->_opnds[1] = op_dst; 3270 n2->_bottom_type = _bottom_type; 3271 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3272 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3273 3274 nodes->push(n1); 3275 nodes->push(n2); 3276 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3277 %} 3278 3279 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3280 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3281 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3282 3283 n_compare->add_req(n_region, n_src); 3284 n_compare->_opnds[0] = op_crx; 3285 n_compare->_opnds[1] = op_src; 3286 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3287 3288 n_shift->add_req(n_region, n_src); 3289 n_shift->_opnds[0] = op_dst; 3290 n_shift->_opnds[1] = op_src; 3291 n_shift->_bottom_type = _bottom_type; 3292 3293 if (VM_Version::has_isel()) { 3294 // use isel instruction with Power 7 3295 3296 decodeN_addNode *n_add_base = new decodeN_addNode(); 3297 n_add_base->add_req(n_region, n_shift); 3298 n_add_base->_opnds[0] = op_dst; 3299 n_add_base->_opnds[1] = op_dst; 3300 n_add_base->_bottom_type = _bottom_type; 3301 3302 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3303 n_cond_set->add_req(n_region, n_compare, n_add_base); 3304 n_cond_set->_opnds[0] = op_dst; 3305 n_cond_set->_opnds[1] = op_crx; 3306 n_cond_set->_opnds[2] = op_dst; 3307 n_cond_set->_bottom_type = _bottom_type; 3308 3309 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3310 ra_->set_oop(n_cond_set, true); 3311 3312 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3313 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3314 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3315 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3316 3317 nodes->push(n_compare); 3318 nodes->push(n_shift); 3319 nodes->push(n_add_base); 3320 nodes->push(n_cond_set); 3321 3322 } else { 3323 // before Power 7 3324 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3325 3326 n_add_base->add_req(n_region, n_compare, n_shift); 3327 n_add_base->_opnds[0] = op_dst; 3328 n_add_base->_opnds[1] = op_crx; 3329 n_add_base->_opnds[2] = op_dst; 3330 n_add_base->_bottom_type = _bottom_type; 3331 3332 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3333 ra_->set_oop(n_add_base, true); 3334 3335 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3336 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3337 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3338 3339 nodes->push(n_compare); 3340 nodes->push(n_shift); 3341 nodes->push(n_add_base); 3342 } 3343 %} 3344 3345 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3346 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3347 n1->add_req(n_region, n_src); 3348 n1->_opnds[0] = op_dst; 3349 n1->_opnds[1] = op_src; 3350 n1->_bottom_type = _bottom_type; 3351 3352 decodeN_addNode *n2 = new decodeN_addNode(); 3353 n2->add_req(n_region, n1); 3354 n2->_opnds[0] = op_dst; 3355 n2->_opnds[1] = op_dst; 3356 n2->_bottom_type = _bottom_type; 3357 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3358 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3359 3360 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3361 ra_->set_oop(n2, true); 3362 3363 nodes->push(n1); 3364 nodes->push(n2); 3365 %} 3366 3367 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3368 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3369 3370 MacroAssembler _masm(&cbuf); 3371 int cc = $cmp$$cmpcode; 3372 int flags_reg = $crx$$reg; 3373 Label done; 3374 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3375 // Branch if not (cmp crx). 3376 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3377 __ mr($dst$$Register, $src$$Register); 3378 // TODO PPC port __ endgroup_if_needed(_size == 12); 3379 __ bind(done); 3380 %} 3381 3382 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3383 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3384 3385 MacroAssembler _masm(&cbuf); 3386 Label done; 3387 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3388 // Branch if not (cmp crx). 3389 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3390 __ li($dst$$Register, $src$$constant); 3391 // TODO PPC port __ endgroup_if_needed(_size == 12); 3392 __ bind(done); 3393 %} 3394 3395 // This enc_class is needed so that scheduler gets proper 3396 // input mapping for latency computation. 3397 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3398 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3399 MacroAssembler _masm(&cbuf); 3400 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3401 %} 3402 3403 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3404 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3405 3406 MacroAssembler _masm(&cbuf); 3407 3408 Label done; 3409 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3410 __ li($dst$$Register, $zero$$constant); 3411 __ beq($crx$$CondRegister, done); 3412 __ li($dst$$Register, $notzero$$constant); 3413 __ bind(done); 3414 %} 3415 3416 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3417 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3418 3419 MacroAssembler _masm(&cbuf); 3420 3421 Label done; 3422 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3423 __ li($dst$$Register, $zero$$constant); 3424 __ beq($crx$$CondRegister, done); 3425 __ li($dst$$Register, $notzero$$constant); 3426 __ bind(done); 3427 %} 3428 3429 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3430 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3431 3432 MacroAssembler _masm(&cbuf); 3433 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3434 Label done; 3435 __ bso($crx$$CondRegister, done); 3436 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3437 // TODO PPC port __ endgroup_if_needed(_size == 12); 3438 __ bind(done); 3439 %} 3440 3441 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3442 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3443 3444 MacroAssembler _masm(&cbuf); 3445 Label done; 3446 __ bso($crx$$CondRegister, done); 3447 __ mffprd($dst$$Register, $src$$FloatRegister); 3448 // TODO PPC port __ endgroup_if_needed(_size == 12); 3449 __ bind(done); 3450 %} 3451 3452 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3453 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3454 3455 MacroAssembler _masm(&cbuf); 3456 Label d; // dummy 3457 __ bind(d); 3458 Label* p = ($lbl$$label); 3459 // `p' is `NULL' when this encoding class is used only to 3460 // determine the size of the encoded instruction. 3461 Label& l = (NULL == p)? d : *(p); 3462 int cc = $cmp$$cmpcode; 3463 int flags_reg = $crx$$reg; 3464 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3465 int bhint = Assembler::bhintNoHint; 3466 3467 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3468 if (_prob <= PROB_NEVER) { 3469 bhint = Assembler::bhintIsNotTaken; 3470 } else if (_prob >= PROB_ALWAYS) { 3471 bhint = Assembler::bhintIsTaken; 3472 } 3473 } 3474 3475 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3476 cc_to_biint(cc, flags_reg), 3477 l); 3478 %} 3479 3480 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3481 // The scheduler doesn't know about branch shortening, so we set the opcode 3482 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3483 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3484 3485 MacroAssembler _masm(&cbuf); 3486 Label d; // dummy 3487 __ bind(d); 3488 Label* p = ($lbl$$label); 3489 // `p' is `NULL' when this encoding class is used only to 3490 // determine the size of the encoded instruction. 3491 Label& l = (NULL == p)? d : *(p); 3492 int cc = $cmp$$cmpcode; 3493 int flags_reg = $crx$$reg; 3494 int bhint = Assembler::bhintNoHint; 3495 3496 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3497 if (_prob <= PROB_NEVER) { 3498 bhint = Assembler::bhintIsNotTaken; 3499 } else if (_prob >= PROB_ALWAYS) { 3500 bhint = Assembler::bhintIsTaken; 3501 } 3502 } 3503 3504 // Tell the conditional far branch to optimize itself when being relocated. 3505 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3506 cc_to_biint(cc, flags_reg), 3507 l, 3508 MacroAssembler::bc_far_optimize_on_relocate); 3509 %} 3510 3511 // Branch used with Power6 scheduling (can be shortened without changing the node). 3512 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3513 // The scheduler doesn't know about branch shortening, so we set the opcode 3514 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3515 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3516 3517 MacroAssembler _masm(&cbuf); 3518 Label d; // dummy 3519 __ bind(d); 3520 Label* p = ($lbl$$label); 3521 // `p' is `NULL' when this encoding class is used only to 3522 // determine the size of the encoded instruction. 3523 Label& l = (NULL == p)? d : *(p); 3524 int cc = $cmp$$cmpcode; 3525 int flags_reg = $crx$$reg; 3526 int bhint = Assembler::bhintNoHint; 3527 3528 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3529 if (_prob <= PROB_NEVER) { 3530 bhint = Assembler::bhintIsNotTaken; 3531 } else if (_prob >= PROB_ALWAYS) { 3532 bhint = Assembler::bhintIsTaken; 3533 } 3534 } 3535 3536 #if 0 // TODO: PPC port 3537 if (_size == 8) { 3538 // Tell the conditional far branch to optimize itself when being relocated. 3539 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3540 cc_to_biint(cc, flags_reg), 3541 l, 3542 MacroAssembler::bc_far_optimize_on_relocate); 3543 } else { 3544 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3545 cc_to_biint(cc, flags_reg), 3546 l); 3547 } 3548 #endif 3549 Unimplemented(); 3550 %} 3551 3552 // Postalloc expand emitter for loading a replicatef float constant from 3553 // the method's TOC. 3554 // Enc_class needed as consttanttablebase is not supported by postalloc 3555 // expand. 3556 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3557 // Create new nodes. 3558 3559 // Make an operand with the bit pattern to load as float. 3560 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3561 3562 loadConLNodesTuple loadConLNodes = 3563 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3564 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3565 3566 // Push new nodes. 3567 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3568 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3569 3570 assert(nodes->length() >= 1, "must have created at least 1 node"); 3571 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3572 %} 3573 3574 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc) %{ 3575 // Create new nodes. 3576 3577 // Make an operand with the bit pattern to load as float. 3578 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3579 immI_0Oper *op_zero = new immI_0Oper(0); 3580 3581 loadConLReplicatedNodesTuple loadConLNodes = 3582 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3583 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num), 3584 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3585 3586 // Push new nodes. 3587 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3588 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3589 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3590 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3591 3592 assert(nodes->length() >= 1, "must have created at least 1 node"); 3593 %} 3594 3595 // This enc_class is needed so that scheduler gets proper 3596 // input mapping for latency computation. 3597 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3598 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3599 // Fake operand dst needed for PPC scheduler. 3600 assert($dst$$constant == 0x0, "dst must be 0x0"); 3601 3602 MacroAssembler _masm(&cbuf); 3603 // Mark the code position where the load from the safepoint 3604 // polling page was emitted as relocInfo::poll_type. 3605 __ relocate(relocInfo::poll_type); 3606 __ load_from_polling_page($poll$$Register); 3607 %} 3608 3609 // A Java static call or a runtime call. 3610 // 3611 // Branch-and-link relative to a trampoline. 3612 // The trampoline loads the target address and does a long branch to there. 3613 // In case we call java, the trampoline branches to a interpreter_stub 3614 // which loads the inline cache and the real call target from the constant pool. 3615 // 3616 // This basically looks like this: 3617 // 3618 // >>>> consts -+ -+ 3619 // | |- offset1 3620 // [call target1] | <-+ 3621 // [IC cache] |- offset2 3622 // [call target2] <--+ 3623 // 3624 // <<<< consts 3625 // >>>> insts 3626 // 3627 // bl offset16 -+ -+ ??? // How many bits available? 3628 // | | 3629 // <<<< insts | | 3630 // >>>> stubs | | 3631 // | |- trampoline_stub_Reloc 3632 // trampoline stub: | <-+ 3633 // r2 = toc | 3634 // r2 = [r2 + offset1] | // Load call target1 from const section 3635 // mtctr r2 | 3636 // bctr |- static_stub_Reloc 3637 // comp_to_interp_stub: <---+ 3638 // r1 = toc 3639 // ICreg = [r1 + IC_offset] // Load IC from const section 3640 // r1 = [r1 + offset2] // Load call target2 from const section 3641 // mtctr r1 3642 // bctr 3643 // 3644 // <<<< stubs 3645 // 3646 // The call instruction in the code either 3647 // - Branches directly to a compiled method if the offset is encodable in instruction. 3648 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3649 // - Branches to the compiled_to_interp stub if the target is interpreted. 3650 // 3651 // Further there are three relocations from the loads to the constants in 3652 // the constant section. 3653 // 3654 // Usage of r1 and r2 in the stubs allows to distinguish them. 3655 enc_class enc_java_static_call(method meth) %{ 3656 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3657 3658 MacroAssembler _masm(&cbuf); 3659 address entry_point = (address)$meth$$method; 3660 3661 if (!_method) { 3662 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3663 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3664 } else { 3665 // Remember the offset not the address. 3666 const int start_offset = __ offset(); 3667 3668 // The trampoline stub. 3669 // No entry point given, use the current pc. 3670 // Make sure branch fits into 3671 if (entry_point == 0) entry_point = __ pc(); 3672 3673 // Put the entry point as a constant into the constant pool. 3674 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3675 if (entry_point_toc_addr == NULL) { 3676 ciEnv::current()->record_out_of_memory_failure(); 3677 return; 3678 } 3679 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3680 3681 // Emit the trampoline stub which will be related to the branch-and-link below. 3682 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3683 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3684 int method_index = resolved_method_index(cbuf); 3685 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3686 : static_call_Relocation::spec(method_index)); 3687 3688 // The real call. 3689 // Note: At this point we do not have the address of the trampoline 3690 // stub, and the entry point might be too far away for bl, so __ pc() 3691 // serves as dummy and the bl will be patched later. 3692 cbuf.set_insts_mark(); 3693 __ bl(__ pc()); // Emits a relocation. 3694 3695 // The stub for call to interpreter. 3696 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3697 if (stub == NULL) { 3698 ciEnv::current()->record_failure("CodeCache is full"); 3699 return; 3700 } 3701 } 3702 %} 3703 3704 // Second node of expanded dynamic call - the call. 3705 enc_class enc_java_dynamic_call_sched(method meth) %{ 3706 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3707 3708 MacroAssembler _masm(&cbuf); 3709 3710 if (!ra_->C->in_scratch_emit_size()) { 3711 // Create a call trampoline stub for the given method. 3712 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3713 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3714 if (entry_point_const == NULL) { 3715 ciEnv::current()->record_out_of_memory_failure(); 3716 return; 3717 } 3718 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3719 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3720 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3721 3722 // Build relocation at call site with ic position as data. 3723 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3724 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3725 "must have one, but can't have both"); 3726 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3727 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3728 "must contain instruction offset"); 3729 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3730 ? _load_ic_hi_node->_cbuf_insts_offset 3731 : _load_ic_node->_cbuf_insts_offset; 3732 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3733 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3734 "should be load from TOC"); 3735 int method_index = resolved_method_index(cbuf); 3736 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3737 } 3738 3739 // At this point I do not have the address of the trampoline stub, 3740 // and the entry point might be too far away for bl. Pc() serves 3741 // as dummy and bl will be patched later. 3742 __ bl((address) __ pc()); 3743 %} 3744 3745 // postalloc expand emitter for virtual calls. 3746 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3747 3748 // Create the nodes for loading the IC from the TOC. 3749 loadConLNodesTuple loadConLNodes_IC = 3750 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3751 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3752 3753 // Create the call node. 3754 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3755 call->_method_handle_invoke = _method_handle_invoke; 3756 call->_vtable_index = _vtable_index; 3757 call->_method = _method; 3758 call->_bci = _bci; 3759 call->_optimized_virtual = _optimized_virtual; 3760 call->_tf = _tf; 3761 call->_entry_point = _entry_point; 3762 call->_cnt = _cnt; 3763 call->_argsize = _argsize; 3764 call->_oop_map = _oop_map; 3765 call->_jvms = _jvms; 3766 call->_jvmadj = _jvmadj; 3767 call->_in_rms = _in_rms; 3768 call->_nesting = _nesting; 3769 call->_override_symbolic_info = _override_symbolic_info; 3770 3771 // New call needs all inputs of old call. 3772 // Req... 3773 for (uint i = 0; i < req(); ++i) { 3774 // The expanded node does not need toc any more. 3775 // Add the inline cache constant here instead. This expresses the 3776 // register of the inline cache must be live at the call. 3777 // Else we would have to adapt JVMState by -1. 3778 if (i == mach_constant_base_node_input()) { 3779 call->add_req(loadConLNodes_IC._last); 3780 } else { 3781 call->add_req(in(i)); 3782 } 3783 } 3784 // ...as well as prec 3785 for (uint i = req(); i < len(); ++i) { 3786 call->add_prec(in(i)); 3787 } 3788 3789 // Remember nodes loading the inline cache into r19. 3790 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3791 call->_load_ic_node = loadConLNodes_IC._small; 3792 3793 // Operands for new nodes. 3794 call->_opnds[0] = _opnds[0]; 3795 call->_opnds[1] = _opnds[1]; 3796 3797 // Only the inline cache is associated with a register. 3798 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3799 3800 // Push new nodes. 3801 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3802 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3803 nodes->push(call); 3804 %} 3805 3806 // Compound version of call dynamic 3807 // Toc is only passed so that it can be used in ins_encode statement. 3808 // In the code we have to use $constanttablebase. 3809 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3810 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3811 MacroAssembler _masm(&cbuf); 3812 int start_offset = __ offset(); 3813 3814 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3815 #if 0 3816 int vtable_index = this->_vtable_index; 3817 if (_vtable_index < 0) { 3818 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3819 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3820 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3821 3822 // Virtual call relocation will point to ic load. 3823 address virtual_call_meta_addr = __ pc(); 3824 // Load a clear inline cache. 3825 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3826 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3827 if (!success) { 3828 ciEnv::current()->record_out_of_memory_failure(); 3829 return; 3830 } 3831 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3832 // to determine who we intended to call. 3833 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3834 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3835 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3836 "Fix constant in ret_addr_offset()"); 3837 } else { 3838 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3839 // Go thru the vtable. Get receiver klass. Receiver already 3840 // checked for non-null. If we'll go thru a C2I adapter, the 3841 // interpreter expects method in R19_method. 3842 3843 __ load_klass(R11_scratch1, R3); 3844 3845 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3846 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3847 __ li(R19_method, v_off); 3848 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3849 // NOTE: for vtable dispatches, the vtable entry will never be 3850 // null. However it may very well end up in handle_wrong_method 3851 // if the method is abstract for the particular class. 3852 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3853 // Call target. Either compiled code or C2I adapter. 3854 __ mtctr(R11_scratch1); 3855 __ bctrl(); 3856 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3857 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3858 } 3859 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3860 "Fix constant in ret_addr_offset()"); 3861 } 3862 #endif 3863 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3864 %} 3865 3866 // a runtime call 3867 enc_class enc_java_to_runtime_call (method meth) %{ 3868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3869 3870 MacroAssembler _masm(&cbuf); 3871 const address start_pc = __ pc(); 3872 3873 #if defined(ABI_ELFv2) 3874 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3875 __ call_c(entry, relocInfo::runtime_call_type); 3876 #else 3877 // The function we're going to call. 3878 FunctionDescriptor fdtemp; 3879 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3880 3881 Register Rtoc = R12_scratch2; 3882 // Calculate the method's TOC. 3883 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3884 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3885 // pool entries; call_c_using_toc will optimize the call. 3886 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3887 if (!success) { 3888 ciEnv::current()->record_out_of_memory_failure(); 3889 return; 3890 } 3891 #endif 3892 3893 // Check the ret_addr_offset. 3894 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3895 "Fix constant in ret_addr_offset()"); 3896 %} 3897 3898 // Move to ctr for leaf call. 3899 // This enc_class is needed so that scheduler gets proper 3900 // input mapping for latency computation. 3901 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3902 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3903 MacroAssembler _masm(&cbuf); 3904 __ mtctr($src$$Register); 3905 %} 3906 3907 // Postalloc expand emitter for runtime leaf calls. 3908 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3909 loadConLNodesTuple loadConLNodes_Entry; 3910 #if defined(ABI_ELFv2) 3911 jlong entry_address = (jlong) this->entry_point(); 3912 assert(entry_address, "need address here"); 3913 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3914 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3915 #else 3916 // Get the struct that describes the function we are about to call. 3917 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3918 assert(fd, "need fd here"); 3919 jlong entry_address = (jlong) fd->entry(); 3920 // new nodes 3921 loadConLNodesTuple loadConLNodes_Env; 3922 loadConLNodesTuple loadConLNodes_Toc; 3923 3924 // Create nodes and operands for loading the entry point. 3925 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3926 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3927 3928 3929 // Create nodes and operands for loading the env pointer. 3930 if (fd->env() != NULL) { 3931 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3932 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3933 } else { 3934 loadConLNodes_Env._large_hi = NULL; 3935 loadConLNodes_Env._large_lo = NULL; 3936 loadConLNodes_Env._small = NULL; 3937 loadConLNodes_Env._last = new loadConL16Node(); 3938 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3939 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3940 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3941 } 3942 3943 // Create nodes and operands for loading the Toc point. 3944 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3945 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3946 #endif // ABI_ELFv2 3947 // mtctr node 3948 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3949 3950 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3951 mtctr->add_req(0, loadConLNodes_Entry._last); 3952 3953 mtctr->_opnds[0] = new iRegLdstOper(); 3954 mtctr->_opnds[1] = new iRegLdstOper(); 3955 3956 // call node 3957 MachCallLeafNode *call = new CallLeafDirectNode(); 3958 3959 call->_opnds[0] = _opnds[0]; 3960 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3961 3962 // Make the new call node look like the old one. 3963 call->_name = _name; 3964 call->_tf = _tf; 3965 call->_entry_point = _entry_point; 3966 call->_cnt = _cnt; 3967 call->_argsize = _argsize; 3968 call->_oop_map = _oop_map; 3969 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3970 call->_jvms = NULL; 3971 call->_jvmadj = _jvmadj; 3972 call->_in_rms = _in_rms; 3973 call->_nesting = _nesting; 3974 3975 3976 // New call needs all inputs of old call. 3977 // Req... 3978 for (uint i = 0; i < req(); ++i) { 3979 if (i != mach_constant_base_node_input()) { 3980 call->add_req(in(i)); 3981 } 3982 } 3983 3984 // These must be reqired edges, as the registers are live up to 3985 // the call. Else the constants are handled as kills. 3986 call->add_req(mtctr); 3987 #if !defined(ABI_ELFv2) 3988 call->add_req(loadConLNodes_Env._last); 3989 call->add_req(loadConLNodes_Toc._last); 3990 #endif 3991 3992 // ...as well as prec 3993 for (uint i = req(); i < len(); ++i) { 3994 call->add_prec(in(i)); 3995 } 3996 3997 // registers 3998 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3999 4000 // Insert the new nodes. 4001 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4002 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4003 #if !defined(ABI_ELFv2) 4004 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4005 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4006 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4007 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4008 #endif 4009 nodes->push(mtctr); 4010 nodes->push(call); 4011 %} 4012 %} 4013 4014 //----------FRAME-------------------------------------------------------------- 4015 // Definition of frame structure and management information. 4016 4017 frame %{ 4018 // What direction does stack grow in (assumed to be same for native & Java). 4019 stack_direction(TOWARDS_LOW); 4020 4021 // These two registers define part of the calling convention between 4022 // compiled code and the interpreter. 4023 4024 // Inline Cache Register or method for I2C. 4025 inline_cache_reg(R19); // R19_method 4026 4027 // Method Oop Register when calling interpreter. 4028 interpreter_method_oop_reg(R19); // R19_method 4029 4030 // Optional: name the operand used by cisc-spilling to access 4031 // [stack_pointer + offset]. 4032 cisc_spilling_operand_name(indOffset); 4033 4034 // Number of stack slots consumed by a Monitor enter. 4035 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4036 4037 // Compiled code's Frame Pointer. 4038 frame_pointer(R1); // R1_SP 4039 4040 // Interpreter stores its frame pointer in a register which is 4041 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4042 // interpreted java to compiled java. 4043 // 4044 // R14_state holds pointer to caller's cInterpreter. 4045 interpreter_frame_pointer(R14); // R14_state 4046 4047 stack_alignment(frame::alignment_in_bytes); 4048 4049 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4050 4051 // Number of outgoing stack slots killed above the 4052 // out_preserve_stack_slots for calls to C. Supports the var-args 4053 // backing area for register parms. 4054 // 4055 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4056 4057 // The after-PROLOG location of the return address. Location of 4058 // return address specifies a type (REG or STACK) and a number 4059 // representing the register number (i.e. - use a register name) or 4060 // stack slot. 4061 // 4062 // A: Link register is stored in stack slot ... 4063 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4064 // J: Therefore, we make sure that the link register is also in R11_scratch1 4065 // at the end of the prolog. 4066 // B: We use R20, now. 4067 //return_addr(REG R20); 4068 4069 // G: After reading the comments made by all the luminaries on their 4070 // failure to tell the compiler where the return address really is, 4071 // I hardly dare to try myself. However, I'm convinced it's in slot 4072 // 4 what apparently works and saves us some spills. 4073 return_addr(STACK 4); 4074 4075 // This is the body of the function 4076 // 4077 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4078 // uint length, // length of array 4079 // bool is_outgoing) 4080 // 4081 // The `sig' array is to be updated. sig[j] represents the location 4082 // of the j-th argument, either a register or a stack slot. 4083 4084 // Comment taken from i486.ad: 4085 // Body of function which returns an integer array locating 4086 // arguments either in registers or in stack slots. Passed an array 4087 // of ideal registers called "sig" and a "length" count. Stack-slot 4088 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4089 // arguments for a CALLEE. Incoming stack arguments are 4090 // automatically biased by the preserve_stack_slots field above. 4091 calling_convention %{ 4092 // No difference between ingoing/outgoing. Just pass false. 4093 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4094 %} 4095 4096 // Comment taken from i486.ad: 4097 // Body of function which returns an integer array locating 4098 // arguments either in registers or in stack slots. Passed an array 4099 // of ideal registers called "sig" and a "length" count. Stack-slot 4100 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4101 // arguments for a CALLEE. Incoming stack arguments are 4102 // automatically biased by the preserve_stack_slots field above. 4103 c_calling_convention %{ 4104 // This is obviously always outgoing. 4105 // C argument in register AND stack slot. 4106 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4107 %} 4108 4109 // Location of native (C/C++) and interpreter return values. This 4110 // is specified to be the same as Java. In the 32-bit VM, long 4111 // values are actually returned from native calls in O0:O1 and 4112 // returned to the interpreter in I0:I1. The copying to and from 4113 // the register pairs is done by the appropriate call and epilog 4114 // opcodes. This simplifies the register allocator. 4115 c_return_value %{ 4116 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4117 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4118 "only return normal values"); 4119 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4120 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4121 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4122 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4123 %} 4124 4125 // Location of compiled Java return values. Same as C 4126 return_value %{ 4127 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4128 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4129 "only return normal values"); 4130 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4131 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4132 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4133 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4134 %} 4135 %} 4136 4137 4138 //----------ATTRIBUTES--------------------------------------------------------- 4139 4140 //----------Operand Attributes------------------------------------------------- 4141 op_attrib op_cost(1); // Required cost attribute. 4142 4143 //----------Instruction Attributes--------------------------------------------- 4144 4145 // Cost attribute. required. 4146 ins_attrib ins_cost(DEFAULT_COST); 4147 4148 // Is this instruction a non-matching short branch variant of some 4149 // long branch? Not required. 4150 ins_attrib ins_short_branch(0); 4151 4152 ins_attrib ins_is_TrapBasedCheckNode(true); 4153 4154 // Number of constants. 4155 // This instruction uses the given number of constants 4156 // (optional attribute). 4157 // This is needed to determine in time whether the constant pool will 4158 // exceed 4000 entries. Before postalloc_expand the overall number of constants 4159 // is determined. It's also used to compute the constant pool size 4160 // in Output(). 4161 ins_attrib ins_num_consts(0); 4162 4163 // Required alignment attribute (must be a power of 2) specifies the 4164 // alignment that some part of the instruction (not necessarily the 4165 // start) requires. If > 1, a compute_padding() function must be 4166 // provided for the instruction. 4167 ins_attrib ins_alignment(1); 4168 4169 // Enforce/prohibit rematerializations. 4170 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4171 // then rematerialization of that instruction is prohibited and the 4172 // instruction's value will be spilled if necessary. 4173 // Causes that MachNode::rematerialize() returns false. 4174 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 4175 // then rematerialization should be enforced and a copy of the instruction 4176 // should be inserted if possible; rematerialization is not guaranteed. 4177 // Note: this may result in rematerializations in front of every use. 4178 // Causes that MachNode::rematerialize() can return true. 4179 // (optional attribute) 4180 ins_attrib ins_cannot_rematerialize(false); 4181 ins_attrib ins_should_rematerialize(false); 4182 4183 // Instruction has variable size depending on alignment. 4184 ins_attrib ins_variable_size_depending_on_alignment(false); 4185 4186 // Instruction is a nop. 4187 ins_attrib ins_is_nop(false); 4188 4189 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4190 ins_attrib ins_use_mach_if_fast_lock_node(false); 4191 4192 // Field for the toc offset of a constant. 4193 // 4194 // This is needed if the toc offset is not encodable as an immediate in 4195 // the PPC load instruction. If so, the upper (hi) bits of the offset are 4196 // added to the toc, and from this a load with immediate is performed. 4197 // With postalloc expand, we get two nodes that require the same offset 4198 // but which don't know about each other. The offset is only known 4199 // when the constant is added to the constant pool during emitting. 4200 // It is generated in the 'hi'-node adding the upper bits, and saved 4201 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 4202 // the offset from there when it gets encoded. 4203 ins_attrib ins_field_const_toc_offset(0); 4204 ins_attrib ins_field_const_toc_offset_hi_node(0); 4205 4206 // A field that can hold the instructions offset in the code buffer. 4207 // Set in the nodes emitter. 4208 ins_attrib ins_field_cbuf_insts_offset(-1); 4209 4210 // Fields for referencing a call's load-IC-node. 4211 // If the toc offset can not be encoded as an immediate in a load, we 4212 // use two nodes. 4213 ins_attrib ins_field_load_ic_hi_node(0); 4214 ins_attrib ins_field_load_ic_node(0); 4215 4216 //----------OPERANDS----------------------------------------------------------- 4217 // Operand definitions must precede instruction definitions for correct 4218 // parsing in the ADLC because operands constitute user defined types 4219 // which are used in instruction definitions. 4220 // 4221 // Formats are generated automatically for constants and base registers. 4222 4223 operand vecX() %{ 4224 constraint(ALLOC_IN_RC(vs_reg)); 4225 match(VecX); 4226 4227 format %{ %} 4228 interface(REG_INTER); 4229 %} 4230 4231 //----------Simple Operands---------------------------------------------------- 4232 // Immediate Operands 4233 4234 // Integer Immediate: 32-bit 4235 operand immI() %{ 4236 match(ConI); 4237 op_cost(40); 4238 format %{ %} 4239 interface(CONST_INTER); 4240 %} 4241 4242 operand immI8() %{ 4243 predicate(Assembler::is_simm(n->get_int(), 8)); 4244 op_cost(0); 4245 match(ConI); 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 // Integer Immediate: 16-bit 4251 operand immI16() %{ 4252 predicate(Assembler::is_simm(n->get_int(), 16)); 4253 op_cost(0); 4254 match(ConI); 4255 format %{ %} 4256 interface(CONST_INTER); 4257 %} 4258 4259 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4260 operand immIhi16() %{ 4261 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4262 match(ConI); 4263 op_cost(0); 4264 format %{ %} 4265 interface(CONST_INTER); 4266 %} 4267 4268 operand immInegpow2() %{ 4269 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4270 match(ConI); 4271 op_cost(0); 4272 format %{ %} 4273 interface(CONST_INTER); 4274 %} 4275 4276 operand immIpow2minus1() %{ 4277 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4278 match(ConI); 4279 op_cost(0); 4280 format %{ %} 4281 interface(CONST_INTER); 4282 %} 4283 4284 operand immIpowerOf2() %{ 4285 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4286 match(ConI); 4287 op_cost(0); 4288 format %{ %} 4289 interface(CONST_INTER); 4290 %} 4291 4292 // Unsigned Integer Immediate: the values 0-31 4293 operand uimmI5() %{ 4294 predicate(Assembler::is_uimm(n->get_int(), 5)); 4295 match(ConI); 4296 op_cost(0); 4297 format %{ %} 4298 interface(CONST_INTER); 4299 %} 4300 4301 // Unsigned Integer Immediate: 6-bit 4302 operand uimmI6() %{ 4303 predicate(Assembler::is_uimm(n->get_int(), 6)); 4304 match(ConI); 4305 op_cost(0); 4306 format %{ %} 4307 interface(CONST_INTER); 4308 %} 4309 4310 // Unsigned Integer Immediate: 6-bit int, greater than 32 4311 operand uimmI6_ge32() %{ 4312 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4313 match(ConI); 4314 op_cost(0); 4315 format %{ %} 4316 interface(CONST_INTER); 4317 %} 4318 4319 // Unsigned Integer Immediate: 15-bit 4320 operand uimmI15() %{ 4321 predicate(Assembler::is_uimm(n->get_int(), 15)); 4322 match(ConI); 4323 op_cost(0); 4324 format %{ %} 4325 interface(CONST_INTER); 4326 %} 4327 4328 // Unsigned Integer Immediate: 16-bit 4329 operand uimmI16() %{ 4330 predicate(Assembler::is_uimm(n->get_int(), 16)); 4331 match(ConI); 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // constant 'int 0'. 4338 operand immI_0() %{ 4339 predicate(n->get_int() == 0); 4340 match(ConI); 4341 op_cost(0); 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // constant 'int 1'. 4347 operand immI_1() %{ 4348 predicate(n->get_int() == 1); 4349 match(ConI); 4350 op_cost(0); 4351 format %{ %} 4352 interface(CONST_INTER); 4353 %} 4354 4355 // constant 'int -1'. 4356 operand immI_minus1() %{ 4357 predicate(n->get_int() == -1); 4358 match(ConI); 4359 op_cost(0); 4360 format %{ %} 4361 interface(CONST_INTER); 4362 %} 4363 4364 // int value 16. 4365 operand immI_16() %{ 4366 predicate(n->get_int() == 16); 4367 match(ConI); 4368 op_cost(0); 4369 format %{ %} 4370 interface(CONST_INTER); 4371 %} 4372 4373 // int value 24. 4374 operand immI_24() %{ 4375 predicate(n->get_int() == 24); 4376 match(ConI); 4377 op_cost(0); 4378 format %{ %} 4379 interface(CONST_INTER); 4380 %} 4381 4382 // Compressed oops constants 4383 // Pointer Immediate 4384 operand immN() %{ 4385 match(ConN); 4386 4387 op_cost(10); 4388 format %{ %} 4389 interface(CONST_INTER); 4390 %} 4391 4392 // NULL Pointer Immediate 4393 operand immN_0() %{ 4394 predicate(n->get_narrowcon() == 0); 4395 match(ConN); 4396 4397 op_cost(0); 4398 format %{ %} 4399 interface(CONST_INTER); 4400 %} 4401 4402 // Compressed klass constants 4403 operand immNKlass() %{ 4404 match(ConNKlass); 4405 4406 op_cost(0); 4407 format %{ %} 4408 interface(CONST_INTER); 4409 %} 4410 4411 // This operand can be used to avoid matching of an instruct 4412 // with chain rule. 4413 operand immNKlass_NM() %{ 4414 match(ConNKlass); 4415 predicate(false); 4416 op_cost(0); 4417 format %{ %} 4418 interface(CONST_INTER); 4419 %} 4420 4421 // Pointer Immediate: 64-bit 4422 operand immP() %{ 4423 match(ConP); 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 // Operand to avoid match of loadConP. 4430 // This operand can be used to avoid matching of an instruct 4431 // with chain rule. 4432 operand immP_NM() %{ 4433 match(ConP); 4434 predicate(false); 4435 op_cost(0); 4436 format %{ %} 4437 interface(CONST_INTER); 4438 %} 4439 4440 // costant 'pointer 0'. 4441 operand immP_0() %{ 4442 predicate(n->get_ptr() == 0); 4443 match(ConP); 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447 %} 4448 4449 // pointer 0x0 or 0x1 4450 operand immP_0or1() %{ 4451 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4452 match(ConP); 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 operand immL() %{ 4459 match(ConL); 4460 op_cost(40); 4461 format %{ %} 4462 interface(CONST_INTER); 4463 %} 4464 4465 operand immLmax30() %{ 4466 predicate((n->get_long() <= 30)); 4467 match(ConL); 4468 op_cost(0); 4469 format %{ %} 4470 interface(CONST_INTER); 4471 %} 4472 4473 // Long Immediate: 16-bit 4474 operand immL16() %{ 4475 predicate(Assembler::is_simm(n->get_long(), 16)); 4476 match(ConL); 4477 op_cost(0); 4478 format %{ %} 4479 interface(CONST_INTER); 4480 %} 4481 4482 // Long Immediate: 16-bit, 4-aligned 4483 operand immL16Alg4() %{ 4484 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4485 match(ConL); 4486 op_cost(0); 4487 format %{ %} 4488 interface(CONST_INTER); 4489 %} 4490 4491 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4492 operand immL32hi16() %{ 4493 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4494 match(ConL); 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // Long Immediate: 32-bit 4501 operand immL32() %{ 4502 predicate(Assembler::is_simm(n->get_long(), 32)); 4503 match(ConL); 4504 op_cost(0); 4505 format %{ %} 4506 interface(CONST_INTER); 4507 %} 4508 4509 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4510 operand immLhighest16() %{ 4511 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4512 match(ConL); 4513 op_cost(0); 4514 format %{ %} 4515 interface(CONST_INTER); 4516 %} 4517 4518 operand immLnegpow2() %{ 4519 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4520 match(ConL); 4521 op_cost(0); 4522 format %{ %} 4523 interface(CONST_INTER); 4524 %} 4525 4526 operand immLpow2minus1() %{ 4527 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4528 (n->get_long() != (jlong)0xffffffffffffffffL)); 4529 match(ConL); 4530 op_cost(0); 4531 format %{ %} 4532 interface(CONST_INTER); 4533 %} 4534 4535 // constant 'long 0'. 4536 operand immL_0() %{ 4537 predicate(n->get_long() == 0L); 4538 match(ConL); 4539 op_cost(0); 4540 format %{ %} 4541 interface(CONST_INTER); 4542 %} 4543 4544 // constat ' long -1'. 4545 operand immL_minus1() %{ 4546 predicate(n->get_long() == -1L); 4547 match(ConL); 4548 op_cost(0); 4549 format %{ %} 4550 interface(CONST_INTER); 4551 %} 4552 4553 // Long Immediate: low 32-bit mask 4554 operand immL_32bits() %{ 4555 predicate(n->get_long() == 0xFFFFFFFFL); 4556 match(ConL); 4557 op_cost(0); 4558 format %{ %} 4559 interface(CONST_INTER); 4560 %} 4561 4562 // Unsigned Long Immediate: 16-bit 4563 operand uimmL16() %{ 4564 predicate(Assembler::is_uimm(n->get_long(), 16)); 4565 match(ConL); 4566 op_cost(0); 4567 format %{ %} 4568 interface(CONST_INTER); 4569 %} 4570 4571 // Float Immediate 4572 operand immF() %{ 4573 match(ConF); 4574 op_cost(40); 4575 format %{ %} 4576 interface(CONST_INTER); 4577 %} 4578 4579 // Float Immediate: +0.0f. 4580 operand immF_0() %{ 4581 predicate(jint_cast(n->getf()) == 0); 4582 match(ConF); 4583 4584 op_cost(0); 4585 format %{ %} 4586 interface(CONST_INTER); 4587 %} 4588 4589 // Double Immediate 4590 operand immD() %{ 4591 match(ConD); 4592 op_cost(40); 4593 format %{ %} 4594 interface(CONST_INTER); 4595 %} 4596 4597 // Integer Register Operands 4598 // Integer Destination Register 4599 // See definition of reg_class bits32_reg_rw. 4600 operand iRegIdst() %{ 4601 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4602 match(RegI); 4603 match(rscratch1RegI); 4604 match(rscratch2RegI); 4605 match(rarg1RegI); 4606 match(rarg2RegI); 4607 match(rarg3RegI); 4608 match(rarg4RegI); 4609 format %{ %} 4610 interface(REG_INTER); 4611 %} 4612 4613 // Integer Source Register 4614 // See definition of reg_class bits32_reg_ro. 4615 operand iRegIsrc() %{ 4616 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4617 match(RegI); 4618 match(rscratch1RegI); 4619 match(rscratch2RegI); 4620 match(rarg1RegI); 4621 match(rarg2RegI); 4622 match(rarg3RegI); 4623 match(rarg4RegI); 4624 format %{ %} 4625 interface(REG_INTER); 4626 %} 4627 4628 operand rscratch1RegI() %{ 4629 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4630 match(iRegIdst); 4631 format %{ %} 4632 interface(REG_INTER); 4633 %} 4634 4635 operand rscratch2RegI() %{ 4636 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4637 match(iRegIdst); 4638 format %{ %} 4639 interface(REG_INTER); 4640 %} 4641 4642 operand rarg1RegI() %{ 4643 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4644 match(iRegIdst); 4645 format %{ %} 4646 interface(REG_INTER); 4647 %} 4648 4649 operand rarg2RegI() %{ 4650 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4651 match(iRegIdst); 4652 format %{ %} 4653 interface(REG_INTER); 4654 %} 4655 4656 operand rarg3RegI() %{ 4657 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4658 match(iRegIdst); 4659 format %{ %} 4660 interface(REG_INTER); 4661 %} 4662 4663 operand rarg4RegI() %{ 4664 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4665 match(iRegIdst); 4666 format %{ %} 4667 interface(REG_INTER); 4668 %} 4669 4670 operand rarg1RegL() %{ 4671 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4672 match(iRegLdst); 4673 format %{ %} 4674 interface(REG_INTER); 4675 %} 4676 4677 operand rarg2RegL() %{ 4678 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4679 match(iRegLdst); 4680 format %{ %} 4681 interface(REG_INTER); 4682 %} 4683 4684 operand rarg3RegL() %{ 4685 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4686 match(iRegLdst); 4687 format %{ %} 4688 interface(REG_INTER); 4689 %} 4690 4691 operand rarg4RegL() %{ 4692 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4693 match(iRegLdst); 4694 format %{ %} 4695 interface(REG_INTER); 4696 %} 4697 4698 // Pointer Destination Register 4699 // See definition of reg_class bits64_reg_rw. 4700 operand iRegPdst() %{ 4701 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4702 match(RegP); 4703 match(rscratch1RegP); 4704 match(rscratch2RegP); 4705 match(rarg1RegP); 4706 match(rarg2RegP); 4707 match(rarg3RegP); 4708 match(rarg4RegP); 4709 format %{ %} 4710 interface(REG_INTER); 4711 %} 4712 4713 // Pointer Destination Register 4714 // Operand not using r11 and r12 (killed in epilog). 4715 operand iRegPdstNoScratch() %{ 4716 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4717 match(RegP); 4718 match(rarg1RegP); 4719 match(rarg2RegP); 4720 match(rarg3RegP); 4721 match(rarg4RegP); 4722 format %{ %} 4723 interface(REG_INTER); 4724 %} 4725 4726 // Pointer Source Register 4727 // See definition of reg_class bits64_reg_ro. 4728 operand iRegPsrc() %{ 4729 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4730 match(RegP); 4731 match(iRegPdst); 4732 match(rscratch1RegP); 4733 match(rscratch2RegP); 4734 match(rarg1RegP); 4735 match(rarg2RegP); 4736 match(rarg3RegP); 4737 match(rarg4RegP); 4738 match(threadRegP); 4739 format %{ %} 4740 interface(REG_INTER); 4741 %} 4742 4743 // Thread operand. 4744 operand threadRegP() %{ 4745 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4746 match(iRegPdst); 4747 format %{ "R16" %} 4748 interface(REG_INTER); 4749 %} 4750 4751 operand rscratch1RegP() %{ 4752 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4753 match(iRegPdst); 4754 format %{ "R11" %} 4755 interface(REG_INTER); 4756 %} 4757 4758 operand rscratch2RegP() %{ 4759 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4760 match(iRegPdst); 4761 format %{ %} 4762 interface(REG_INTER); 4763 %} 4764 4765 operand rarg1RegP() %{ 4766 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4767 match(iRegPdst); 4768 format %{ %} 4769 interface(REG_INTER); 4770 %} 4771 4772 operand rarg2RegP() %{ 4773 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4774 match(iRegPdst); 4775 format %{ %} 4776 interface(REG_INTER); 4777 %} 4778 4779 operand rarg3RegP() %{ 4780 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4781 match(iRegPdst); 4782 format %{ %} 4783 interface(REG_INTER); 4784 %} 4785 4786 operand rarg4RegP() %{ 4787 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4788 match(iRegPdst); 4789 format %{ %} 4790 interface(REG_INTER); 4791 %} 4792 4793 operand iRegNsrc() %{ 4794 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4795 match(RegN); 4796 match(iRegNdst); 4797 4798 format %{ %} 4799 interface(REG_INTER); 4800 %} 4801 4802 operand iRegNdst() %{ 4803 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4804 match(RegN); 4805 4806 format %{ %} 4807 interface(REG_INTER); 4808 %} 4809 4810 // Long Destination Register 4811 // See definition of reg_class bits64_reg_rw. 4812 operand iRegLdst() %{ 4813 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4814 match(RegL); 4815 match(rscratch1RegL); 4816 match(rscratch2RegL); 4817 format %{ %} 4818 interface(REG_INTER); 4819 %} 4820 4821 // Long Source Register 4822 // See definition of reg_class bits64_reg_ro. 4823 operand iRegLsrc() %{ 4824 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4825 match(RegL); 4826 match(iRegLdst); 4827 match(rscratch1RegL); 4828 match(rscratch2RegL); 4829 format %{ %} 4830 interface(REG_INTER); 4831 %} 4832 4833 // Special operand for ConvL2I. 4834 operand iRegL2Isrc(iRegLsrc reg) %{ 4835 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4836 match(ConvL2I reg); 4837 format %{ "ConvL2I($reg)" %} 4838 interface(REG_INTER) 4839 %} 4840 4841 operand rscratch1RegL() %{ 4842 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4843 match(RegL); 4844 format %{ %} 4845 interface(REG_INTER); 4846 %} 4847 4848 operand rscratch2RegL() %{ 4849 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4850 match(RegL); 4851 format %{ %} 4852 interface(REG_INTER); 4853 %} 4854 4855 // Condition Code Flag Registers 4856 operand flagsReg() %{ 4857 constraint(ALLOC_IN_RC(int_flags)); 4858 match(RegFlags); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 operand flagsRegSrc() %{ 4864 constraint(ALLOC_IN_RC(int_flags_ro)); 4865 match(RegFlags); 4866 match(flagsReg); 4867 match(flagsRegCR0); 4868 format %{ %} 4869 interface(REG_INTER); 4870 %} 4871 4872 // Condition Code Flag Register CR0 4873 operand flagsRegCR0() %{ 4874 constraint(ALLOC_IN_RC(int_flags_CR0)); 4875 match(RegFlags); 4876 format %{ "CR0" %} 4877 interface(REG_INTER); 4878 %} 4879 4880 operand flagsRegCR1() %{ 4881 constraint(ALLOC_IN_RC(int_flags_CR1)); 4882 match(RegFlags); 4883 format %{ "CR1" %} 4884 interface(REG_INTER); 4885 %} 4886 4887 operand flagsRegCR6() %{ 4888 constraint(ALLOC_IN_RC(int_flags_CR6)); 4889 match(RegFlags); 4890 format %{ "CR6" %} 4891 interface(REG_INTER); 4892 %} 4893 4894 operand regCTR() %{ 4895 constraint(ALLOC_IN_RC(ctr_reg)); 4896 // RegFlags should work. Introducing a RegSpecial type would cause a 4897 // lot of changes. 4898 match(RegFlags); 4899 format %{"SR_CTR" %} 4900 interface(REG_INTER); 4901 %} 4902 4903 operand regD() %{ 4904 constraint(ALLOC_IN_RC(dbl_reg)); 4905 match(RegD); 4906 format %{ %} 4907 interface(REG_INTER); 4908 %} 4909 4910 operand regF() %{ 4911 constraint(ALLOC_IN_RC(flt_reg)); 4912 match(RegF); 4913 format %{ %} 4914 interface(REG_INTER); 4915 %} 4916 4917 // Special Registers 4918 4919 // Method Register 4920 operand inline_cache_regP(iRegPdst reg) %{ 4921 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4922 match(reg); 4923 format %{ %} 4924 interface(REG_INTER); 4925 %} 4926 4927 operand compiler_method_oop_regP(iRegPdst reg) %{ 4928 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4929 match(reg); 4930 format %{ %} 4931 interface(REG_INTER); 4932 %} 4933 4934 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4935 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4936 match(reg); 4937 format %{ %} 4938 interface(REG_INTER); 4939 %} 4940 4941 // Operands to remove register moves in unscaled mode. 4942 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4943 operand iRegP2N(iRegPsrc reg) %{ 4944 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4945 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4946 match(EncodeP reg); 4947 format %{ "$reg" %} 4948 interface(REG_INTER) 4949 %} 4950 4951 operand iRegN2P(iRegNsrc reg) %{ 4952 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4953 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4954 match(DecodeN reg); 4955 format %{ "$reg" %} 4956 interface(REG_INTER) 4957 %} 4958 4959 operand iRegN2P_klass(iRegNsrc reg) %{ 4960 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4961 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4962 match(DecodeNKlass reg); 4963 format %{ "$reg" %} 4964 interface(REG_INTER) 4965 %} 4966 4967 //----------Complex Operands--------------------------------------------------- 4968 // Indirect Memory Reference 4969 operand indirect(iRegPsrc reg) %{ 4970 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4971 match(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 // Indirect with Offset 4983 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4984 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4985 match(AddP reg offset); 4986 op_cost(100); 4987 format %{ "[$reg + $offset]" %} 4988 interface(MEMORY_INTER) %{ 4989 base($reg); 4990 index(0x0); 4991 scale(0x0); 4992 disp($offset); 4993 %} 4994 %} 4995 4996 // Indirect with 4-aligned Offset 4997 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4998 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4999 match(AddP reg offset); 5000 op_cost(100); 5001 format %{ "[$reg + $offset]" %} 5002 interface(MEMORY_INTER) %{ 5003 base($reg); 5004 index(0x0); 5005 scale(0x0); 5006 disp($offset); 5007 %} 5008 %} 5009 5010 //----------Complex Operands for Compressed OOPs------------------------------- 5011 // Compressed OOPs with narrow_oop_shift == 0. 5012 5013 // Indirect Memory Reference, compressed OOP 5014 operand indirectNarrow(iRegNsrc reg) %{ 5015 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5016 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5017 match(DecodeN reg); 5018 op_cost(100); 5019 format %{ "[$reg]" %} 5020 interface(MEMORY_INTER) %{ 5021 base($reg); 5022 index(0x0); 5023 scale(0x0); 5024 disp(0x0); 5025 %} 5026 %} 5027 5028 operand indirectNarrow_klass(iRegNsrc reg) %{ 5029 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5030 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5031 match(DecodeNKlass reg); 5032 op_cost(100); 5033 format %{ "[$reg]" %} 5034 interface(MEMORY_INTER) %{ 5035 base($reg); 5036 index(0x0); 5037 scale(0x0); 5038 disp(0x0); 5039 %} 5040 %} 5041 5042 // Indirect with Offset, compressed OOP 5043 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5044 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5045 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5046 match(AddP (DecodeN reg) offset); 5047 op_cost(100); 5048 format %{ "[$reg + $offset]" %} 5049 interface(MEMORY_INTER) %{ 5050 base($reg); 5051 index(0x0); 5052 scale(0x0); 5053 disp($offset); 5054 %} 5055 %} 5056 5057 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5058 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5059 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5060 match(AddP (DecodeNKlass reg) offset); 5061 op_cost(100); 5062 format %{ "[$reg + $offset]" %} 5063 interface(MEMORY_INTER) %{ 5064 base($reg); 5065 index(0x0); 5066 scale(0x0); 5067 disp($offset); 5068 %} 5069 %} 5070 5071 // Indirect with 4-aligned Offset, compressed OOP 5072 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5073 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5074 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5075 match(AddP (DecodeN reg) offset); 5076 op_cost(100); 5077 format %{ "[$reg + $offset]" %} 5078 interface(MEMORY_INTER) %{ 5079 base($reg); 5080 index(0x0); 5081 scale(0x0); 5082 disp($offset); 5083 %} 5084 %} 5085 5086 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5087 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5088 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5089 match(AddP (DecodeNKlass reg) offset); 5090 op_cost(100); 5091 format %{ "[$reg + $offset]" %} 5092 interface(MEMORY_INTER) %{ 5093 base($reg); 5094 index(0x0); 5095 scale(0x0); 5096 disp($offset); 5097 %} 5098 %} 5099 5100 //----------Special Memory Operands-------------------------------------------- 5101 // Stack Slot Operand 5102 // 5103 // This operand is used for loading and storing temporary values on 5104 // the stack where a match requires a value to flow through memory. 5105 operand stackSlotI(sRegI reg) %{ 5106 constraint(ALLOC_IN_RC(stack_slots)); 5107 op_cost(100); 5108 //match(RegI); 5109 format %{ "[sp+$reg]" %} 5110 interface(MEMORY_INTER) %{ 5111 base(0x1); // R1_SP 5112 index(0x0); 5113 scale(0x0); 5114 disp($reg); // Stack Offset 5115 %} 5116 %} 5117 5118 operand stackSlotL(sRegL reg) %{ 5119 constraint(ALLOC_IN_RC(stack_slots)); 5120 op_cost(100); 5121 //match(RegL); 5122 format %{ "[sp+$reg]" %} 5123 interface(MEMORY_INTER) %{ 5124 base(0x1); // R1_SP 5125 index(0x0); 5126 scale(0x0); 5127 disp($reg); // Stack Offset 5128 %} 5129 %} 5130 5131 operand stackSlotP(sRegP reg) %{ 5132 constraint(ALLOC_IN_RC(stack_slots)); 5133 op_cost(100); 5134 //match(RegP); 5135 format %{ "[sp+$reg]" %} 5136 interface(MEMORY_INTER) %{ 5137 base(0x1); // R1_SP 5138 index(0x0); 5139 scale(0x0); 5140 disp($reg); // Stack Offset 5141 %} 5142 %} 5143 5144 operand stackSlotF(sRegF reg) %{ 5145 constraint(ALLOC_IN_RC(stack_slots)); 5146 op_cost(100); 5147 //match(RegF); 5148 format %{ "[sp+$reg]" %} 5149 interface(MEMORY_INTER) %{ 5150 base(0x1); // R1_SP 5151 index(0x0); 5152 scale(0x0); 5153 disp($reg); // Stack Offset 5154 %} 5155 %} 5156 5157 operand stackSlotD(sRegD reg) %{ 5158 constraint(ALLOC_IN_RC(stack_slots)); 5159 op_cost(100); 5160 //match(RegD); 5161 format %{ "[sp+$reg]" %} 5162 interface(MEMORY_INTER) %{ 5163 base(0x1); // R1_SP 5164 index(0x0); 5165 scale(0x0); 5166 disp($reg); // Stack Offset 5167 %} 5168 %} 5169 5170 // Operands for expressing Control Flow 5171 // NOTE: Label is a predefined operand which should not be redefined in 5172 // the AD file. It is generically handled within the ADLC. 5173 5174 //----------Conditional Branch Operands---------------------------------------- 5175 // Comparison Op 5176 // 5177 // This is the operation of the comparison, and is limited to the 5178 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5179 // (!=). 5180 // 5181 // Other attributes of the comparison, such as unsignedness, are specified 5182 // by the comparison instruction that sets a condition code flags register. 5183 // That result is represented by a flags operand whose subtype is appropriate 5184 // to the unsignedness (etc.) of the comparison. 5185 // 5186 // Later, the instruction which matches both the Comparison Op (a Bool) and 5187 // the flags (produced by the Cmp) specifies the coding of the comparison op 5188 // by matching a specific subtype of Bool operand below. 5189 5190 // When used for floating point comparisons: unordered same as less. 5191 operand cmpOp() %{ 5192 match(Bool); 5193 format %{ "" %} 5194 interface(COND_INTER) %{ 5195 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5196 // BO & BI 5197 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5198 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5199 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5200 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5201 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5202 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5203 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5204 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5205 %} 5206 %} 5207 5208 //----------OPERAND CLASSES---------------------------------------------------- 5209 // Operand Classes are groups of operands that are used to simplify 5210 // instruction definitions by not requiring the AD writer to specify 5211 // seperate instructions for every form of operand when the 5212 // instruction accepts multiple operand types with the same basic 5213 // encoding and format. The classic case of this is memory operands. 5214 // Indirect is not included since its use is limited to Compare & Swap. 5215 5216 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5217 // Memory operand where offsets are 4-aligned. Required for ld, std. 5218 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5219 opclass indirectMemory(indirect, indirectNarrow); 5220 5221 // Special opclass for I and ConvL2I. 5222 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5223 5224 // Operand classes to match encode and decode. iRegN_P2N is only used 5225 // for storeN. I have never seen an encode node elsewhere. 5226 opclass iRegN_P2N(iRegNsrc, iRegP2N); 5227 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5228 5229 //----------PIPELINE----------------------------------------------------------- 5230 5231 pipeline %{ 5232 5233 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5234 // J. Res. & Dev., No. 1, Jan. 2002. 5235 5236 //----------ATTRIBUTES--------------------------------------------------------- 5237 attributes %{ 5238 5239 // Power4 instructions are of fixed length. 5240 fixed_size_instructions; 5241 5242 // TODO: if `bundle' means number of instructions fetched 5243 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5244 // max instructions issued per cycle, this is 5. 5245 max_instructions_per_bundle = 8; 5246 5247 // A Power4 instruction is 4 bytes long. 5248 instruction_unit_size = 4; 5249 5250 // The Power4 processor fetches 64 bytes... 5251 instruction_fetch_unit_size = 64; 5252 5253 // ...in one line 5254 instruction_fetch_units = 1 5255 5256 // Unused, list one so that array generated by adlc is not empty. 5257 // Aix compiler chokes if _nop_count = 0. 5258 nops(fxNop); 5259 %} 5260 5261 //----------RESOURCES---------------------------------------------------------- 5262 // Resources are the functional units available to the machine 5263 resources( 5264 PPC_BR, // branch unit 5265 PPC_CR, // condition unit 5266 PPC_FX1, // integer arithmetic unit 1 5267 PPC_FX2, // integer arithmetic unit 2 5268 PPC_LDST1, // load/store unit 1 5269 PPC_LDST2, // load/store unit 2 5270 PPC_FP1, // float arithmetic unit 1 5271 PPC_FP2, // float arithmetic unit 2 5272 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5273 PPC_FX = PPC_FX1 | PPC_FX2, 5274 PPC_FP = PPC_FP1 | PPC_FP2 5275 ); 5276 5277 //----------PIPELINE DESCRIPTION----------------------------------------------- 5278 // Pipeline Description specifies the stages in the machine's pipeline 5279 pipe_desc( 5280 // Power4 longest pipeline path 5281 PPC_IF, // instruction fetch 5282 PPC_IC, 5283 //PPC_BP, // branch prediction 5284 PPC_D0, // decode 5285 PPC_D1, // decode 5286 PPC_D2, // decode 5287 PPC_D3, // decode 5288 PPC_Xfer1, 5289 PPC_GD, // group definition 5290 PPC_MP, // map 5291 PPC_ISS, // issue 5292 PPC_RF, // resource fetch 5293 PPC_EX1, // execute (all units) 5294 PPC_EX2, // execute (FP, LDST) 5295 PPC_EX3, // execute (FP, LDST) 5296 PPC_EX4, // execute (FP) 5297 PPC_EX5, // execute (FP) 5298 PPC_EX6, // execute (FP) 5299 PPC_WB, // write back 5300 PPC_Xfer2, 5301 PPC_CP 5302 ); 5303 5304 //----------PIPELINE CLASSES--------------------------------------------------- 5305 // Pipeline Classes describe the stages in which input and output are 5306 // referenced by the hardware pipeline. 5307 5308 // Simple pipeline classes. 5309 5310 // Default pipeline class. 5311 pipe_class pipe_class_default() %{ 5312 single_instruction; 5313 fixed_latency(2); 5314 %} 5315 5316 // Pipeline class for empty instructions. 5317 pipe_class pipe_class_empty() %{ 5318 single_instruction; 5319 fixed_latency(0); 5320 %} 5321 5322 // Pipeline class for compares. 5323 pipe_class pipe_class_compare() %{ 5324 single_instruction; 5325 fixed_latency(16); 5326 %} 5327 5328 // Pipeline class for traps. 5329 pipe_class pipe_class_trap() %{ 5330 single_instruction; 5331 fixed_latency(100); 5332 %} 5333 5334 // Pipeline class for memory operations. 5335 pipe_class pipe_class_memory() %{ 5336 single_instruction; 5337 fixed_latency(16); 5338 %} 5339 5340 // Pipeline class for call. 5341 pipe_class pipe_class_call() %{ 5342 single_instruction; 5343 fixed_latency(100); 5344 %} 5345 5346 // Define the class for the Nop node. 5347 define %{ 5348 MachNop = pipe_class_default; 5349 %} 5350 5351 %} 5352 5353 //----------INSTRUCTIONS------------------------------------------------------- 5354 5355 // Naming of instructions: 5356 // opA_operB / opA_operB_operC: 5357 // Operation 'op' with one or two source operands 'oper'. Result 5358 // type is A, source operand types are B and C. 5359 // Iff A == B == C, B and C are left out. 5360 // 5361 // The instructions are ordered according to the following scheme: 5362 // - loads 5363 // - load constants 5364 // - prefetch 5365 // - store 5366 // - encode/decode 5367 // - membar 5368 // - conditional moves 5369 // - compare & swap 5370 // - arithmetic and logic operations 5371 // * int: Add, Sub, Mul, Div, Mod 5372 // * int: lShift, arShift, urShift, rot 5373 // * float: Add, Sub, Mul, Div 5374 // * and, or, xor ... 5375 // - register moves: float <-> int, reg <-> stack, repl 5376 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5377 // - conv (low level type cast requiring bit changes (sign extend etc) 5378 // - compares, range & zero checks. 5379 // - branches 5380 // - complex operations, intrinsics, min, max, replicate 5381 // - lock 5382 // - Calls 5383 // 5384 // If there are similar instructions with different types they are sorted: 5385 // int before float 5386 // small before big 5387 // signed before unsigned 5388 // e.g., loadS before loadUS before loadI before loadF. 5389 5390 5391 //----------Load/Store Instructions-------------------------------------------- 5392 5393 //----------Load Instructions-------------------------------------------------- 5394 5395 // Converts byte to int. 5396 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 5397 // reuses the 'amount' operand, but adlc expects that operand specification 5398 // and operands in match rule are equivalent. 5399 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5400 effect(DEF dst, USE src); 5401 format %{ "EXTSB $dst, $src \t// byte->int" %} 5402 size(4); 5403 ins_encode %{ 5404 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5405 __ extsb($dst$$Register, $src$$Register); 5406 %} 5407 ins_pipe(pipe_class_default); 5408 %} 5409 5410 instruct loadUB_indirect(iRegIdst dst, indirectMemory 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_indirect_ac(iRegIdst dst, indirectMemory 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_indirect_Ex(iRegIdst dst, indirectMemory 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 expand %{ 5440 iRegIdst tmp; 5441 loadUB_indirect(tmp, mem); 5442 convB2I_reg_2(dst, tmp); 5443 %} 5444 %} 5445 5446 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5447 match(Set dst (LoadB mem)); 5448 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5449 expand %{ 5450 iRegIdst tmp; 5451 loadUB_indirect_ac(tmp, mem); 5452 convB2I_reg_2(dst, tmp); 5453 %} 5454 %} 5455 5456 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5457 // match-rule, false predicate 5458 match(Set dst (LoadB mem)); 5459 predicate(false); 5460 5461 format %{ "LBZ $dst, $mem" %} 5462 size(4); 5463 ins_encode( enc_lbz(dst, mem) ); 5464 ins_pipe(pipe_class_memory); 5465 %} 5466 5467 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5468 // match-rule, false predicate 5469 match(Set dst (LoadB mem)); 5470 predicate(false); 5471 5472 format %{ "LBZ $dst, $mem\n\t" 5473 "TWI $dst\n\t" 5474 "ISYNC" %} 5475 size(12); 5476 ins_encode( enc_lbz_ac(dst, mem) ); 5477 ins_pipe(pipe_class_memory); 5478 %} 5479 5480 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5481 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5482 match(Set dst (LoadB mem)); 5483 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5484 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5485 5486 expand %{ 5487 iRegIdst tmp; 5488 loadUB_indOffset16(tmp, mem); 5489 convB2I_reg_2(dst, tmp); 5490 %} 5491 %} 5492 5493 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5494 match(Set dst (LoadB mem)); 5495 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5496 5497 expand %{ 5498 iRegIdst tmp; 5499 loadUB_indOffset16_ac(tmp, mem); 5500 convB2I_reg_2(dst, tmp); 5501 %} 5502 %} 5503 5504 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5505 instruct loadUB(iRegIdst dst, memory mem) %{ 5506 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5507 match(Set dst (LoadUB mem)); 5508 ins_cost(MEMORY_REF_COST); 5509 5510 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5511 size(4); 5512 ins_encode( enc_lbz(dst, mem) ); 5513 ins_pipe(pipe_class_memory); 5514 %} 5515 5516 // Load Unsigned Byte (8bit UNsigned) acquire. 5517 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5518 match(Set dst (LoadUB mem)); 5519 ins_cost(3*MEMORY_REF_COST); 5520 5521 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5522 "TWI $dst\n\t" 5523 "ISYNC" %} 5524 size(12); 5525 ins_encode( enc_lbz_ac(dst, mem) ); 5526 ins_pipe(pipe_class_memory); 5527 %} 5528 5529 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5530 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5531 match(Set dst (ConvI2L (LoadUB mem))); 5532 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5533 ins_cost(MEMORY_REF_COST); 5534 5535 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5536 size(4); 5537 ins_encode( enc_lbz(dst, mem) ); 5538 ins_pipe(pipe_class_memory); 5539 %} 5540 5541 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5542 match(Set dst (ConvI2L (LoadUB mem))); 5543 ins_cost(3*MEMORY_REF_COST); 5544 5545 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5546 "TWI $dst\n\t" 5547 "ISYNC" %} 5548 size(12); 5549 ins_encode( enc_lbz_ac(dst, mem) ); 5550 ins_pipe(pipe_class_memory); 5551 %} 5552 5553 // Load Short (16bit signed) 5554 instruct loadS(iRegIdst dst, memory mem) %{ 5555 match(Set dst (LoadS mem)); 5556 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5557 ins_cost(MEMORY_REF_COST); 5558 5559 format %{ "LHA $dst, $mem" %} 5560 size(4); 5561 ins_encode %{ 5562 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5563 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5564 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5565 %} 5566 ins_pipe(pipe_class_memory); 5567 %} 5568 5569 // Load Short (16bit signed) acquire. 5570 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5571 match(Set dst (LoadS mem)); 5572 ins_cost(3*MEMORY_REF_COST); 5573 5574 format %{ "LHA $dst, $mem\t acquire\n\t" 5575 "TWI $dst\n\t" 5576 "ISYNC" %} 5577 size(12); 5578 ins_encode %{ 5579 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5580 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5581 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5582 __ twi_0($dst$$Register); 5583 __ isync(); 5584 %} 5585 ins_pipe(pipe_class_memory); 5586 %} 5587 5588 // Load Char (16bit unsigned) 5589 instruct loadUS(iRegIdst dst, memory mem) %{ 5590 match(Set dst (LoadUS mem)); 5591 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5592 ins_cost(MEMORY_REF_COST); 5593 5594 format %{ "LHZ $dst, $mem" %} 5595 size(4); 5596 ins_encode( enc_lhz(dst, mem) ); 5597 ins_pipe(pipe_class_memory); 5598 %} 5599 5600 // Load Char (16bit unsigned) acquire. 5601 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5602 match(Set dst (LoadUS mem)); 5603 ins_cost(3*MEMORY_REF_COST); 5604 5605 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5606 "TWI $dst\n\t" 5607 "ISYNC" %} 5608 size(12); 5609 ins_encode( enc_lhz_ac(dst, mem) ); 5610 ins_pipe(pipe_class_memory); 5611 %} 5612 5613 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5614 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5615 match(Set dst (ConvI2L (LoadUS mem))); 5616 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5617 ins_cost(MEMORY_REF_COST); 5618 5619 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5620 size(4); 5621 ins_encode( enc_lhz(dst, mem) ); 5622 ins_pipe(pipe_class_memory); 5623 %} 5624 5625 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5626 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5627 match(Set dst (ConvI2L (LoadUS mem))); 5628 ins_cost(3*MEMORY_REF_COST); 5629 5630 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5631 "TWI $dst\n\t" 5632 "ISYNC" %} 5633 size(12); 5634 ins_encode( enc_lhz_ac(dst, mem) ); 5635 ins_pipe(pipe_class_memory); 5636 %} 5637 5638 // Load Integer. 5639 instruct loadI(iRegIdst dst, memory mem) %{ 5640 match(Set dst (LoadI mem)); 5641 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5642 ins_cost(MEMORY_REF_COST); 5643 5644 format %{ "LWZ $dst, $mem" %} 5645 size(4); 5646 ins_encode( enc_lwz(dst, mem) ); 5647 ins_pipe(pipe_class_memory); 5648 %} 5649 5650 // Load Integer acquire. 5651 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5652 match(Set dst (LoadI mem)); 5653 ins_cost(3*MEMORY_REF_COST); 5654 5655 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5656 "TWI $dst\n\t" 5657 "ISYNC" %} 5658 size(12); 5659 ins_encode( enc_lwz_ac(dst, mem) ); 5660 ins_pipe(pipe_class_memory); 5661 %} 5662 5663 // Match loading integer and casting it to unsigned int in 5664 // long register. 5665 // LoadI + ConvI2L + AndL 0xffffffff. 5666 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5667 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5668 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5669 ins_cost(MEMORY_REF_COST); 5670 5671 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5672 size(4); 5673 ins_encode( enc_lwz(dst, mem) ); 5674 ins_pipe(pipe_class_memory); 5675 %} 5676 5677 // Match loading integer and casting it to long. 5678 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5679 match(Set dst (ConvI2L (LoadI mem))); 5680 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5681 ins_cost(MEMORY_REF_COST); 5682 5683 format %{ "LWA $dst, $mem \t// loadI2L" %} 5684 size(4); 5685 ins_encode %{ 5686 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5687 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5688 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5689 %} 5690 ins_pipe(pipe_class_memory); 5691 %} 5692 5693 // Match loading integer and casting it to long - acquire. 5694 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5695 match(Set dst (ConvI2L (LoadI mem))); 5696 ins_cost(3*MEMORY_REF_COST); 5697 5698 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5699 "TWI $dst\n\t" 5700 "ISYNC" %} 5701 size(12); 5702 ins_encode %{ 5703 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5704 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5705 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5706 __ twi_0($dst$$Register); 5707 __ isync(); 5708 %} 5709 ins_pipe(pipe_class_memory); 5710 %} 5711 5712 // Load Long - aligned 5713 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5714 match(Set dst (LoadL mem)); 5715 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5716 ins_cost(MEMORY_REF_COST); 5717 5718 format %{ "LD $dst, $mem \t// long" %} 5719 size(4); 5720 ins_encode( enc_ld(dst, mem) ); 5721 ins_pipe(pipe_class_memory); 5722 %} 5723 5724 // Load Long - aligned acquire. 5725 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5726 match(Set dst (LoadL mem)); 5727 ins_cost(3*MEMORY_REF_COST); 5728 5729 format %{ "LD $dst, $mem \t// long acquire\n\t" 5730 "TWI $dst\n\t" 5731 "ISYNC" %} 5732 size(12); 5733 ins_encode( enc_ld_ac(dst, mem) ); 5734 ins_pipe(pipe_class_memory); 5735 %} 5736 5737 // Load Long - UNaligned 5738 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5739 match(Set dst (LoadL_unaligned mem)); 5740 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5741 ins_cost(MEMORY_REF_COST); 5742 5743 format %{ "LD $dst, $mem \t// unaligned long" %} 5744 size(4); 5745 ins_encode( enc_ld(dst, mem) ); 5746 ins_pipe(pipe_class_memory); 5747 %} 5748 5749 // Load nodes for superwords 5750 5751 // Load Aligned Packed Byte 5752 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5753 predicate(n->as_LoadVector()->memory_size() == 8); 5754 match(Set dst (LoadVector mem)); 5755 ins_cost(MEMORY_REF_COST); 5756 5757 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5758 size(4); 5759 ins_encode( enc_ld(dst, mem) ); 5760 ins_pipe(pipe_class_memory); 5761 %} 5762 5763 // Load Aligned Packed Byte 5764 instruct loadV16(vecX dst, indirect mem) %{ 5765 predicate(n->as_LoadVector()->memory_size() == 16); 5766 match(Set dst (LoadVector mem)); 5767 ins_cost(MEMORY_REF_COST); 5768 5769 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5770 size(4); 5771 ins_encode %{ 5772 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5773 %} 5774 ins_pipe(pipe_class_default); 5775 %} 5776 5777 // Load Range, range = array length (=jint) 5778 instruct loadRange(iRegIdst dst, memory mem) %{ 5779 match(Set dst (LoadRange mem)); 5780 ins_cost(MEMORY_REF_COST); 5781 5782 format %{ "LWZ $dst, $mem \t// range" %} 5783 size(4); 5784 ins_encode( enc_lwz(dst, mem) ); 5785 ins_pipe(pipe_class_memory); 5786 %} 5787 5788 // Load Compressed Pointer 5789 instruct loadN(iRegNdst dst, memory mem) %{ 5790 match(Set dst (LoadN mem)); 5791 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5792 ins_cost(MEMORY_REF_COST); 5793 5794 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5795 size(4); 5796 ins_encode( enc_lwz(dst, mem) ); 5797 ins_pipe(pipe_class_memory); 5798 %} 5799 5800 // Load Compressed Pointer acquire. 5801 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5802 match(Set dst (LoadN mem)); 5803 ins_cost(3*MEMORY_REF_COST); 5804 5805 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5806 "TWI $dst\n\t" 5807 "ISYNC" %} 5808 size(12); 5809 ins_encode( enc_lwz_ac(dst, mem) ); 5810 ins_pipe(pipe_class_memory); 5811 %} 5812 5813 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5814 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5815 match(Set dst (DecodeN (LoadN mem))); 5816 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5817 ins_cost(MEMORY_REF_COST); 5818 5819 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5820 size(4); 5821 ins_encode( enc_lwz(dst, mem) ); 5822 ins_pipe(pipe_class_memory); 5823 %} 5824 5825 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5826 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5827 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5828 _kids[0]->_leaf->as_Load()->is_unordered()); 5829 ins_cost(MEMORY_REF_COST); 5830 5831 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5832 size(4); 5833 ins_encode( enc_lwz(dst, mem) ); 5834 ins_pipe(pipe_class_memory); 5835 %} 5836 5837 // Load Pointer 5838 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5839 match(Set dst (LoadP mem)); 5840 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5841 ins_cost(MEMORY_REF_COST); 5842 5843 format %{ "LD $dst, $mem \t// ptr" %} 5844 size(4); 5845 ins_encode( enc_ld(dst, mem) ); 5846 ins_pipe(pipe_class_memory); 5847 %} 5848 5849 // Load Pointer acquire. 5850 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5851 match(Set dst (LoadP mem)); 5852 ins_cost(3*MEMORY_REF_COST); 5853 5854 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5855 "TWI $dst\n\t" 5856 "ISYNC" %} 5857 size(12); 5858 ins_encode( enc_ld_ac(dst, mem) ); 5859 ins_pipe(pipe_class_memory); 5860 %} 5861 5862 // LoadP + CastP2L 5863 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5864 match(Set dst (CastP2X (LoadP mem))); 5865 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5866 ins_cost(MEMORY_REF_COST); 5867 5868 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5869 size(4); 5870 ins_encode( enc_ld(dst, mem) ); 5871 ins_pipe(pipe_class_memory); 5872 %} 5873 5874 // Load compressed klass pointer. 5875 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5876 match(Set dst (LoadNKlass mem)); 5877 ins_cost(MEMORY_REF_COST); 5878 5879 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5880 size(4); 5881 ins_encode( enc_lwz(dst, mem) ); 5882 ins_pipe(pipe_class_memory); 5883 %} 5884 5885 // Load Klass Pointer 5886 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5887 match(Set dst (LoadKlass mem)); 5888 ins_cost(MEMORY_REF_COST); 5889 5890 format %{ "LD $dst, $mem \t// klass ptr" %} 5891 size(4); 5892 ins_encode( enc_ld(dst, mem) ); 5893 ins_pipe(pipe_class_memory); 5894 %} 5895 5896 // Load Float 5897 instruct loadF(regF dst, memory mem) %{ 5898 match(Set dst (LoadF mem)); 5899 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5900 ins_cost(MEMORY_REF_COST); 5901 5902 format %{ "LFS $dst, $mem" %} 5903 size(4); 5904 ins_encode %{ 5905 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5906 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5907 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5908 %} 5909 ins_pipe(pipe_class_memory); 5910 %} 5911 5912 // Load Float acquire. 5913 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5914 match(Set dst (LoadF mem)); 5915 effect(TEMP cr0); 5916 ins_cost(3*MEMORY_REF_COST); 5917 5918 format %{ "LFS $dst, $mem \t// acquire\n\t" 5919 "FCMPU cr0, $dst, $dst\n\t" 5920 "BNE cr0, next\n" 5921 "next:\n\t" 5922 "ISYNC" %} 5923 size(16); 5924 ins_encode %{ 5925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5926 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5927 Label next; 5928 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5929 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5930 __ bne(CCR0, next); 5931 __ bind(next); 5932 __ isync(); 5933 %} 5934 ins_pipe(pipe_class_memory); 5935 %} 5936 5937 // Load Double - aligned 5938 instruct loadD(regD dst, memory mem) %{ 5939 match(Set dst (LoadD mem)); 5940 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5941 ins_cost(MEMORY_REF_COST); 5942 5943 format %{ "LFD $dst, $mem" %} 5944 size(4); 5945 ins_encode( enc_lfd(dst, mem) ); 5946 ins_pipe(pipe_class_memory); 5947 %} 5948 5949 // Load Double - aligned acquire. 5950 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5951 match(Set dst (LoadD mem)); 5952 effect(TEMP cr0); 5953 ins_cost(3*MEMORY_REF_COST); 5954 5955 format %{ "LFD $dst, $mem \t// acquire\n\t" 5956 "FCMPU cr0, $dst, $dst\n\t" 5957 "BNE cr0, next\n" 5958 "next:\n\t" 5959 "ISYNC" %} 5960 size(16); 5961 ins_encode %{ 5962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5963 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5964 Label next; 5965 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5966 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5967 __ bne(CCR0, next); 5968 __ bind(next); 5969 __ isync(); 5970 %} 5971 ins_pipe(pipe_class_memory); 5972 %} 5973 5974 // Load Double - UNaligned 5975 instruct loadD_unaligned(regD dst, memory mem) %{ 5976 match(Set dst (LoadD_unaligned mem)); 5977 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5978 ins_cost(MEMORY_REF_COST); 5979 5980 format %{ "LFD $dst, $mem" %} 5981 size(4); 5982 ins_encode( enc_lfd(dst, mem) ); 5983 ins_pipe(pipe_class_memory); 5984 %} 5985 5986 //----------Constants-------------------------------------------------------- 5987 5988 // Load MachConstantTableBase: add hi offset to global toc. 5989 // TODO: Handle hidden register r29 in bundler! 5990 instruct loadToc_hi(iRegLdst dst) %{ 5991 effect(DEF dst); 5992 ins_cost(DEFAULT_COST); 5993 5994 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5995 size(4); 5996 ins_encode %{ 5997 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5998 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5999 %} 6000 ins_pipe(pipe_class_default); 6001 %} 6002 6003 // Load MachConstantTableBase: add lo offset to global toc. 6004 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6005 effect(DEF dst, USE src); 6006 ins_cost(DEFAULT_COST); 6007 6008 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6009 size(4); 6010 ins_encode %{ 6011 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6012 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6013 %} 6014 ins_pipe(pipe_class_default); 6015 %} 6016 6017 // Load 16-bit integer constant 0xssss???? 6018 instruct loadConI16(iRegIdst dst, immI16 src) %{ 6019 match(Set dst src); 6020 6021 format %{ "LI $dst, $src" %} 6022 size(4); 6023 ins_encode %{ 6024 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6025 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6026 %} 6027 ins_pipe(pipe_class_default); 6028 %} 6029 6030 // Load integer constant 0x????0000 6031 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6032 match(Set dst src); 6033 ins_cost(DEFAULT_COST); 6034 6035 format %{ "LIS $dst, $src.hi" %} 6036 size(4); 6037 ins_encode %{ 6038 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6039 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6040 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6041 %} 6042 ins_pipe(pipe_class_default); 6043 %} 6044 6045 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6046 // and sign extended), this adds the low 16 bits. 6047 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6048 // no match-rule, false predicate 6049 effect(DEF dst, USE src1, USE src2); 6050 predicate(false); 6051 6052 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6053 size(4); 6054 ins_encode %{ 6055 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6056 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6057 %} 6058 ins_pipe(pipe_class_default); 6059 %} 6060 6061 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6062 match(Set dst src); 6063 ins_cost(DEFAULT_COST*2); 6064 6065 expand %{ 6066 // Would like to use $src$$constant. 6067 immI16 srcLo %{ _opnds[1]->constant() %} 6068 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6069 immIhi16 srcHi %{ _opnds[1]->constant() %} 6070 iRegIdst tmpI; 6071 loadConIhi16(tmpI, srcHi); 6072 loadConI32_lo16(dst, tmpI, srcLo); 6073 %} 6074 %} 6075 6076 // No constant pool entries required. 6077 instruct loadConL16(iRegLdst dst, immL16 src) %{ 6078 match(Set dst src); 6079 6080 format %{ "LI $dst, $src \t// long" %} 6081 size(4); 6082 ins_encode %{ 6083 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6084 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6085 %} 6086 ins_pipe(pipe_class_default); 6087 %} 6088 6089 // Load long constant 0xssssssss????0000 6090 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6091 match(Set dst src); 6092 ins_cost(DEFAULT_COST); 6093 6094 format %{ "LIS $dst, $src.hi \t// long" %} 6095 size(4); 6096 ins_encode %{ 6097 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6098 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6099 %} 6100 ins_pipe(pipe_class_default); 6101 %} 6102 6103 // To load a 32 bit constant: merge lower 16 bits into already loaded 6104 // high 16 bits. 6105 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6106 // no match-rule, false predicate 6107 effect(DEF dst, USE src1, USE src2); 6108 predicate(false); 6109 6110 format %{ "ORI $dst, $src1, $src2.lo" %} 6111 size(4); 6112 ins_encode %{ 6113 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6114 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6115 %} 6116 ins_pipe(pipe_class_default); 6117 %} 6118 6119 // Load 32-bit long constant 6120 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6121 match(Set dst src); 6122 ins_cost(DEFAULT_COST*2); 6123 6124 expand %{ 6125 // Would like to use $src$$constant. 6126 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6127 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6128 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6129 iRegLdst tmpL; 6130 loadConL32hi16(tmpL, srcHi); 6131 loadConL32_lo16(dst, tmpL, srcLo); 6132 %} 6133 %} 6134 6135 // Load long constant 0x????000000000000. 6136 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6137 match(Set dst src); 6138 ins_cost(DEFAULT_COST); 6139 6140 expand %{ 6141 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6142 immI shift32 %{ 32 %} 6143 iRegLdst tmpL; 6144 loadConL32hi16(tmpL, srcHi); 6145 lshiftL_regL_immI(dst, tmpL, shift32); 6146 %} 6147 %} 6148 6149 // Expand node for constant pool load: small offset. 6150 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6151 effect(DEF dst, USE src, USE toc); 6152 ins_cost(MEMORY_REF_COST); 6153 6154 ins_num_consts(1); 6155 // Needed so that CallDynamicJavaDirect can compute the address of this 6156 // instruction for relocation. 6157 ins_field_cbuf_insts_offset(int); 6158 6159 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6160 size(4); 6161 ins_encode( enc_load_long_constL(dst, src, toc) ); 6162 ins_pipe(pipe_class_memory); 6163 %} 6164 6165 // Expand node for constant pool load: large offset. 6166 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6167 effect(DEF dst, USE src, USE toc); 6168 predicate(false); 6169 6170 ins_num_consts(1); 6171 ins_field_const_toc_offset(int); 6172 // Needed so that CallDynamicJavaDirect can compute the address of this 6173 // instruction for relocation. 6174 ins_field_cbuf_insts_offset(int); 6175 6176 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6177 size(4); 6178 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6179 ins_pipe(pipe_class_default); 6180 %} 6181 6182 // Expand node for constant pool load: large offset. 6183 // No constant pool entries required. 6184 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6185 effect(DEF dst, USE src, USE base); 6186 predicate(false); 6187 6188 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6189 6190 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6191 size(4); 6192 ins_encode %{ 6193 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6194 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6195 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6196 %} 6197 ins_pipe(pipe_class_memory); 6198 %} 6199 6200 // Load long constant from constant table. Expand in case of 6201 // offset > 16 bit is needed. 6202 // Adlc adds toc node MachConstantTableBase. 6203 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6204 match(Set dst src); 6205 ins_cost(MEMORY_REF_COST); 6206 6207 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6208 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6209 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6210 %} 6211 6212 // Load NULL as compressed oop. 6213 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6214 match(Set dst src); 6215 ins_cost(DEFAULT_COST); 6216 6217 format %{ "LI $dst, $src \t// compressed ptr" %} 6218 size(4); 6219 ins_encode %{ 6220 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6221 __ li($dst$$Register, 0); 6222 %} 6223 ins_pipe(pipe_class_default); 6224 %} 6225 6226 // Load hi part of compressed oop constant. 6227 instruct loadConN_hi(iRegNdst dst, immN src) %{ 6228 effect(DEF dst, USE src); 6229 ins_cost(DEFAULT_COST); 6230 6231 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6232 size(4); 6233 ins_encode %{ 6234 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6235 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6236 %} 6237 ins_pipe(pipe_class_default); 6238 %} 6239 6240 // Add lo part of compressed oop constant to already loaded hi part. 6241 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6242 effect(DEF dst, USE src1, USE src2); 6243 ins_cost(DEFAULT_COST); 6244 6245 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6246 size(4); 6247 ins_encode %{ 6248 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6249 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6250 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6251 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6252 __ relocate(rspec, 1); 6253 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6254 %} 6255 ins_pipe(pipe_class_default); 6256 %} 6257 6258 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6259 effect(DEF dst, USE src, USE shift, USE mask_begin); 6260 6261 size(4); 6262 ins_encode %{ 6263 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6264 %} 6265 ins_pipe(pipe_class_default); 6266 %} 6267 6268 // Needed to postalloc expand loadConN: ConN is loaded as ConI 6269 // leaving the upper 32 bits with sign-extension bits. 6270 // This clears these bits: dst = src & 0xFFFFFFFF. 6271 // TODO: Eventually call this maskN_regN_FFFFFFFF. 6272 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6273 effect(DEF dst, USE src); 6274 predicate(false); 6275 6276 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6277 size(4); 6278 ins_encode %{ 6279 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6280 __ clrldi($dst$$Register, $src$$Register, 0x20); 6281 %} 6282 ins_pipe(pipe_class_default); 6283 %} 6284 6285 // Optimize DecodeN for disjoint base. 6286 // Load base of compressed oops into a register 6287 instruct loadBase(iRegLdst dst) %{ 6288 effect(DEF dst); 6289 6290 format %{ "LoadConst $dst, heapbase" %} 6291 ins_encode %{ 6292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6293 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6294 %} 6295 ins_pipe(pipe_class_default); 6296 %} 6297 6298 // Loading ConN must be postalloc expanded so that edges between 6299 // the nodes are safe. They may not interfere with a safepoint. 6300 // GL TODO: This needs three instructions: better put this into the constant pool. 6301 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6302 match(Set dst src); 6303 ins_cost(DEFAULT_COST*2); 6304 6305 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6306 postalloc_expand %{ 6307 MachNode *m1 = new loadConN_hiNode(); 6308 MachNode *m2 = new loadConN_loNode(); 6309 MachNode *m3 = new clearMs32bNode(); 6310 m1->add_req(NULL); 6311 m2->add_req(NULL, m1); 6312 m3->add_req(NULL, m2); 6313 m1->_opnds[0] = op_dst; 6314 m1->_opnds[1] = op_src; 6315 m2->_opnds[0] = op_dst; 6316 m2->_opnds[1] = op_dst; 6317 m2->_opnds[2] = op_src; 6318 m3->_opnds[0] = op_dst; 6319 m3->_opnds[1] = op_dst; 6320 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6321 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6322 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6323 nodes->push(m1); 6324 nodes->push(m2); 6325 nodes->push(m3); 6326 %} 6327 %} 6328 6329 // We have seen a safepoint between the hi and lo parts, and this node was handled 6330 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6331 // not a narrow oop. 6332 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6333 match(Set dst src); 6334 effect(DEF dst, USE src); 6335 ins_cost(DEFAULT_COST); 6336 6337 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6338 size(4); 6339 ins_encode %{ 6340 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6341 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6342 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6343 %} 6344 ins_pipe(pipe_class_default); 6345 %} 6346 6347 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6348 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6349 match(Set dst src1); 6350 effect(TEMP src2); 6351 ins_cost(DEFAULT_COST); 6352 6353 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6354 size(4); 6355 ins_encode %{ 6356 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6357 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6358 %} 6359 ins_pipe(pipe_class_default); 6360 %} 6361 6362 // This needs a match rule so that build_oop_map knows this is 6363 // not a narrow oop. 6364 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6365 match(Set dst src1); 6366 effect(TEMP src2); 6367 ins_cost(DEFAULT_COST); 6368 6369 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6370 size(4); 6371 ins_encode %{ 6372 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6373 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6374 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6375 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6376 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6377 6378 __ relocate(rspec, 1); 6379 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6380 %} 6381 ins_pipe(pipe_class_default); 6382 %} 6383 6384 // Loading ConNKlass must be postalloc expanded so that edges between 6385 // the nodes are safe. They may not interfere with a safepoint. 6386 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6387 match(Set dst src); 6388 ins_cost(DEFAULT_COST*2); 6389 6390 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6391 postalloc_expand %{ 6392 // Load high bits into register. Sign extended. 6393 MachNode *m1 = new loadConNKlass_hiNode(); 6394 m1->add_req(NULL); 6395 m1->_opnds[0] = op_dst; 6396 m1->_opnds[1] = op_src; 6397 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6398 nodes->push(m1); 6399 6400 MachNode *m2 = m1; 6401 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6402 // Value might be 1-extended. Mask out these bits. 6403 m2 = new loadConNKlass_maskNode(); 6404 m2->add_req(NULL, m1); 6405 m2->_opnds[0] = op_dst; 6406 m2->_opnds[1] = op_src; 6407 m2->_opnds[2] = op_dst; 6408 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6409 nodes->push(m2); 6410 } 6411 6412 MachNode *m3 = new loadConNKlass_loNode(); 6413 m3->add_req(NULL, m2); 6414 m3->_opnds[0] = op_dst; 6415 m3->_opnds[1] = op_src; 6416 m3->_opnds[2] = op_dst; 6417 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6418 nodes->push(m3); 6419 %} 6420 %} 6421 6422 // 0x1 is used in object initialization (initial object header). 6423 // No constant pool entries required. 6424 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6425 match(Set dst src); 6426 6427 format %{ "LI $dst, $src \t// ptr" %} 6428 size(4); 6429 ins_encode %{ 6430 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6431 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6432 %} 6433 ins_pipe(pipe_class_default); 6434 %} 6435 6436 // Expand node for constant pool load: small offset. 6437 // The match rule is needed to generate the correct bottom_type(), 6438 // however this node should never match. The use of predicate is not 6439 // possible since ADLC forbids predicates for chain rules. The higher 6440 // costs do not prevent matching in this case. For that reason the 6441 // operand immP_NM with predicate(false) is used. 6442 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6443 match(Set dst src); 6444 effect(TEMP toc); 6445 6446 ins_num_consts(1); 6447 6448 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6449 size(4); 6450 ins_encode( enc_load_long_constP(dst, src, toc) ); 6451 ins_pipe(pipe_class_memory); 6452 %} 6453 6454 // Expand node for constant pool load: large offset. 6455 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6456 effect(DEF dst, USE src, USE toc); 6457 predicate(false); 6458 6459 ins_num_consts(1); 6460 ins_field_const_toc_offset(int); 6461 6462 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6463 size(4); 6464 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6465 ins_pipe(pipe_class_default); 6466 %} 6467 6468 // Expand node for constant pool load: large offset. 6469 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6470 match(Set dst src); 6471 effect(TEMP base); 6472 6473 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6474 6475 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6476 size(4); 6477 ins_encode %{ 6478 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6479 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6480 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6481 %} 6482 ins_pipe(pipe_class_memory); 6483 %} 6484 6485 // Load pointer constant from constant table. Expand in case an 6486 // offset > 16 bit is needed. 6487 // Adlc adds toc node MachConstantTableBase. 6488 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6489 match(Set dst src); 6490 ins_cost(MEMORY_REF_COST); 6491 6492 // This rule does not use "expand" because then 6493 // the result type is not known to be an Oop. An ADLC 6494 // enhancement will be needed to make that work - not worth it! 6495 6496 // If this instruction rematerializes, it prolongs the live range 6497 // of the toc node, causing illegal graphs. 6498 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6499 ins_cannot_rematerialize(true); 6500 6501 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6502 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6503 %} 6504 6505 // Expand node for constant pool load: small offset. 6506 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6507 effect(DEF dst, USE src, USE toc); 6508 ins_cost(MEMORY_REF_COST); 6509 6510 ins_num_consts(1); 6511 6512 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6513 size(4); 6514 ins_encode %{ 6515 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6516 address float_address = __ float_constant($src$$constant); 6517 if (float_address == NULL) { 6518 ciEnv::current()->record_out_of_memory_failure(); 6519 return; 6520 } 6521 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6522 %} 6523 ins_pipe(pipe_class_memory); 6524 %} 6525 6526 // Expand node for constant pool load: large offset. 6527 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6528 effect(DEF dst, USE src, USE toc); 6529 ins_cost(MEMORY_REF_COST); 6530 6531 ins_num_consts(1); 6532 6533 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6534 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6535 "ADDIS $toc, $toc, -offset_hi"%} 6536 size(12); 6537 ins_encode %{ 6538 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6539 FloatRegister Rdst = $dst$$FloatRegister; 6540 Register Rtoc = $toc$$Register; 6541 address float_address = __ float_constant($src$$constant); 6542 if (float_address == NULL) { 6543 ciEnv::current()->record_out_of_memory_failure(); 6544 return; 6545 } 6546 int offset = __ offset_to_method_toc(float_address); 6547 int hi = (offset + (1<<15))>>16; 6548 int lo = offset - hi * (1<<16); 6549 6550 __ addis(Rtoc, Rtoc, hi); 6551 __ lfs(Rdst, lo, Rtoc); 6552 __ addis(Rtoc, Rtoc, -hi); 6553 %} 6554 ins_pipe(pipe_class_memory); 6555 %} 6556 6557 // Adlc adds toc node MachConstantTableBase. 6558 instruct loadConF_Ex(regF dst, immF src) %{ 6559 match(Set dst src); 6560 ins_cost(MEMORY_REF_COST); 6561 6562 // See loadConP. 6563 ins_cannot_rematerialize(true); 6564 6565 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6566 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6567 %} 6568 6569 // Expand node for constant pool load: small offset. 6570 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6571 effect(DEF dst, USE src, USE toc); 6572 ins_cost(MEMORY_REF_COST); 6573 6574 ins_num_consts(1); 6575 6576 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6577 size(4); 6578 ins_encode %{ 6579 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6580 address float_address = __ double_constant($src$$constant); 6581 if (float_address == NULL) { 6582 ciEnv::current()->record_out_of_memory_failure(); 6583 return; 6584 } 6585 int offset = __ offset_to_method_toc(float_address); 6586 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6587 %} 6588 ins_pipe(pipe_class_memory); 6589 %} 6590 6591 // Expand node for constant pool load: large offset. 6592 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6593 effect(DEF dst, USE src, USE toc); 6594 ins_cost(MEMORY_REF_COST); 6595 6596 ins_num_consts(1); 6597 6598 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6599 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6600 "ADDIS $toc, $toc, -offset_hi" %} 6601 size(12); 6602 ins_encode %{ 6603 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6604 FloatRegister Rdst = $dst$$FloatRegister; 6605 Register Rtoc = $toc$$Register; 6606 address float_address = __ double_constant($src$$constant); 6607 if (float_address == NULL) { 6608 ciEnv::current()->record_out_of_memory_failure(); 6609 return; 6610 } 6611 int offset = __ offset_to_method_toc(float_address); 6612 int hi = (offset + (1<<15))>>16; 6613 int lo = offset - hi * (1<<16); 6614 6615 __ addis(Rtoc, Rtoc, hi); 6616 __ lfd(Rdst, lo, Rtoc); 6617 __ addis(Rtoc, Rtoc, -hi); 6618 %} 6619 ins_pipe(pipe_class_memory); 6620 %} 6621 6622 // Adlc adds toc node MachConstantTableBase. 6623 instruct loadConD_Ex(regD dst, immD src) %{ 6624 match(Set dst src); 6625 ins_cost(MEMORY_REF_COST); 6626 6627 // See loadConP. 6628 ins_cannot_rematerialize(true); 6629 6630 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6631 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6632 %} 6633 6634 // Prefetch instructions. 6635 // Must be safe to execute with invalid address (cannot fault). 6636 6637 // Special prefetch versions which use the dcbz instruction. 6638 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6639 match(PrefetchAllocation (AddP mem src)); 6640 predicate(AllocatePrefetchStyle == 3); 6641 ins_cost(MEMORY_REF_COST); 6642 6643 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6644 size(4); 6645 ins_encode %{ 6646 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6647 __ dcbz($src$$Register, $mem$$base$$Register); 6648 %} 6649 ins_pipe(pipe_class_memory); 6650 %} 6651 6652 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6653 match(PrefetchAllocation mem); 6654 predicate(AllocatePrefetchStyle == 3); 6655 ins_cost(MEMORY_REF_COST); 6656 6657 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6658 size(4); 6659 ins_encode %{ 6660 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6661 __ dcbz($mem$$base$$Register); 6662 %} 6663 ins_pipe(pipe_class_memory); 6664 %} 6665 6666 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6667 match(PrefetchAllocation (AddP mem src)); 6668 predicate(AllocatePrefetchStyle != 3); 6669 ins_cost(MEMORY_REF_COST); 6670 6671 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6672 size(4); 6673 ins_encode %{ 6674 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6675 __ dcbtst($src$$Register, $mem$$base$$Register); 6676 %} 6677 ins_pipe(pipe_class_memory); 6678 %} 6679 6680 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6681 match(PrefetchAllocation mem); 6682 predicate(AllocatePrefetchStyle != 3); 6683 ins_cost(MEMORY_REF_COST); 6684 6685 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6686 size(4); 6687 ins_encode %{ 6688 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6689 __ dcbtst($mem$$base$$Register); 6690 %} 6691 ins_pipe(pipe_class_memory); 6692 %} 6693 6694 //----------Store Instructions------------------------------------------------- 6695 6696 // Store Byte 6697 instruct storeB(memory mem, iRegIsrc src) %{ 6698 match(Set mem (StoreB mem src)); 6699 ins_cost(MEMORY_REF_COST); 6700 6701 format %{ "STB $src, $mem \t// byte" %} 6702 size(4); 6703 ins_encode %{ 6704 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6705 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6706 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6707 %} 6708 ins_pipe(pipe_class_memory); 6709 %} 6710 6711 // Store Char/Short 6712 instruct storeC(memory mem, iRegIsrc src) %{ 6713 match(Set mem (StoreC mem src)); 6714 ins_cost(MEMORY_REF_COST); 6715 6716 format %{ "STH $src, $mem \t// short" %} 6717 size(4); 6718 ins_encode %{ 6719 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6720 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6721 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6722 %} 6723 ins_pipe(pipe_class_memory); 6724 %} 6725 6726 // Store Integer 6727 instruct storeI(memory mem, iRegIsrc src) %{ 6728 match(Set mem (StoreI mem src)); 6729 ins_cost(MEMORY_REF_COST); 6730 6731 format %{ "STW $src, $mem" %} 6732 size(4); 6733 ins_encode( enc_stw(src, mem) ); 6734 ins_pipe(pipe_class_memory); 6735 %} 6736 6737 // ConvL2I + StoreI. 6738 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6739 match(Set mem (StoreI mem (ConvL2I src))); 6740 ins_cost(MEMORY_REF_COST); 6741 6742 format %{ "STW l2i($src), $mem" %} 6743 size(4); 6744 ins_encode( enc_stw(src, mem) ); 6745 ins_pipe(pipe_class_memory); 6746 %} 6747 6748 // Store Long 6749 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6750 match(Set mem (StoreL mem src)); 6751 ins_cost(MEMORY_REF_COST); 6752 6753 format %{ "STD $src, $mem \t// long" %} 6754 size(4); 6755 ins_encode( enc_std(src, mem) ); 6756 ins_pipe(pipe_class_memory); 6757 %} 6758 6759 // Store super word nodes. 6760 6761 // Store Aligned Packed Byte long register to memory 6762 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6763 predicate(n->as_StoreVector()->memory_size() == 8); 6764 match(Set mem (StoreVector mem src)); 6765 ins_cost(MEMORY_REF_COST); 6766 6767 format %{ "STD $mem, $src \t// packed8B" %} 6768 size(4); 6769 ins_encode( enc_std(src, mem) ); 6770 ins_pipe(pipe_class_memory); 6771 %} 6772 6773 // Store Packed Byte long register to memory 6774 instruct storeV16(indirect mem, vecX src) %{ 6775 predicate(n->as_StoreVector()->memory_size() == 16); 6776 match(Set mem (StoreVector mem src)); 6777 ins_cost(MEMORY_REF_COST); 6778 6779 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6780 size(4); 6781 ins_encode %{ 6782 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6783 %} 6784 ins_pipe(pipe_class_default); 6785 %} 6786 6787 // Store Compressed Oop 6788 instruct storeN(memory dst, iRegN_P2N src) %{ 6789 match(Set dst (StoreN dst src)); 6790 ins_cost(MEMORY_REF_COST); 6791 6792 format %{ "STW $src, $dst \t// compressed oop" %} 6793 size(4); 6794 ins_encode( enc_stw(src, dst) ); 6795 ins_pipe(pipe_class_memory); 6796 %} 6797 6798 // Store Compressed KLass 6799 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6800 match(Set dst (StoreNKlass dst src)); 6801 ins_cost(MEMORY_REF_COST); 6802 6803 format %{ "STW $src, $dst \t// compressed klass" %} 6804 size(4); 6805 ins_encode( enc_stw(src, dst) ); 6806 ins_pipe(pipe_class_memory); 6807 %} 6808 6809 // Store Pointer 6810 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6811 match(Set dst (StoreP dst src)); 6812 ins_cost(MEMORY_REF_COST); 6813 6814 format %{ "STD $src, $dst \t// ptr" %} 6815 size(4); 6816 ins_encode( enc_std(src, dst) ); 6817 ins_pipe(pipe_class_memory); 6818 %} 6819 6820 // Store Float 6821 instruct storeF(memory mem, regF src) %{ 6822 match(Set mem (StoreF mem src)); 6823 ins_cost(MEMORY_REF_COST); 6824 6825 format %{ "STFS $src, $mem" %} 6826 size(4); 6827 ins_encode( enc_stfs(src, mem) ); 6828 ins_pipe(pipe_class_memory); 6829 %} 6830 6831 // Store Double 6832 instruct storeD(memory mem, regD src) %{ 6833 match(Set mem (StoreD mem src)); 6834 ins_cost(MEMORY_REF_COST); 6835 6836 format %{ "STFD $src, $mem" %} 6837 size(4); 6838 ins_encode( enc_stfd(src, mem) ); 6839 ins_pipe(pipe_class_memory); 6840 %} 6841 6842 //----------Store Instructions With Zeros-------------------------------------- 6843 6844 // Card-mark for CMS garbage collection. 6845 // This cardmark does an optimization so that it must not always 6846 // do a releasing store. For this, it gets the address of 6847 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6848 // (Using releaseFieldAddr in the match rule is a hack.) 6849 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6850 match(Set mem (StoreCM mem releaseFieldAddr)); 6851 effect(TEMP crx); 6852 predicate(false); 6853 ins_cost(MEMORY_REF_COST); 6854 6855 // See loadConP. 6856 ins_cannot_rematerialize(true); 6857 6858 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6859 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6860 ins_pipe(pipe_class_memory); 6861 %} 6862 6863 // Card-mark for CMS garbage collection. 6864 // This cardmark does an optimization so that it must not always 6865 // do a releasing store. For this, it needs the constant address of 6866 // CMSCollectorCardTableModRefBSExt::_requires_release. 6867 // This constant address is split off here by expand so we can use 6868 // adlc / matcher functionality to load it from the constant section. 6869 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6870 match(Set mem (StoreCM mem zero)); 6871 predicate(UseConcMarkSweepGC); 6872 6873 expand %{ 6874 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6875 iRegLdst releaseFieldAddress; 6876 flagsReg crx; 6877 loadConL_Ex(releaseFieldAddress, baseImm); 6878 storeCM_CMS(mem, releaseFieldAddress, crx); 6879 %} 6880 %} 6881 6882 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6883 match(Set mem (StoreCM mem zero)); 6884 predicate(UseG1GC); 6885 ins_cost(MEMORY_REF_COST); 6886 6887 ins_cannot_rematerialize(true); 6888 6889 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6890 size(8); 6891 ins_encode %{ 6892 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6893 __ li(R0, 0); 6894 //__ release(); // G1: oops are allowed to get visible after dirty marking 6895 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6896 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6897 %} 6898 ins_pipe(pipe_class_memory); 6899 %} 6900 6901 // Convert oop pointer into compressed form. 6902 6903 // Nodes for postalloc expand. 6904 6905 // Shift node for expand. 6906 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6907 // The match rule is needed to make it a 'MachTypeNode'! 6908 match(Set dst (EncodeP src)); 6909 predicate(false); 6910 6911 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6912 size(4); 6913 ins_encode %{ 6914 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6915 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6916 %} 6917 ins_pipe(pipe_class_default); 6918 %} 6919 6920 // Add node for expand. 6921 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6922 // The match rule is needed to make it a 'MachTypeNode'! 6923 match(Set dst (EncodeP src)); 6924 predicate(false); 6925 6926 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6927 ins_encode %{ 6928 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6929 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6930 %} 6931 ins_pipe(pipe_class_default); 6932 %} 6933 6934 // Conditional sub base. 6935 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6936 // The match rule is needed to make it a 'MachTypeNode'! 6937 match(Set dst (EncodeP (Binary crx src1))); 6938 predicate(false); 6939 6940 format %{ "BEQ $crx, done\n\t" 6941 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6942 "done:" %} 6943 ins_encode %{ 6944 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6945 Label done; 6946 __ beq($crx$$CondRegister, done); 6947 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6948 __ bind(done); 6949 %} 6950 ins_pipe(pipe_class_default); 6951 %} 6952 6953 // Power 7 can use isel instruction 6954 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6955 // The match rule is needed to make it a 'MachTypeNode'! 6956 match(Set dst (EncodeP (Binary crx src1))); 6957 predicate(false); 6958 6959 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6960 size(4); 6961 ins_encode %{ 6962 // This is a Power7 instruction for which no machine description exists. 6963 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6964 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6965 %} 6966 ins_pipe(pipe_class_default); 6967 %} 6968 6969 // Disjoint narrow oop base. 6970 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6971 match(Set dst (EncodeP src)); 6972 predicate(Universe::narrow_oop_base_disjoint()); 6973 6974 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6975 size(4); 6976 ins_encode %{ 6977 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6978 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6979 %} 6980 ins_pipe(pipe_class_default); 6981 %} 6982 6983 // shift != 0, base != 0 6984 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6985 match(Set dst (EncodeP src)); 6986 effect(TEMP crx); 6987 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6988 Universe::narrow_oop_shift() != 0 && 6989 Universe::narrow_oop_base_overlaps()); 6990 6991 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6992 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6993 %} 6994 6995 // shift != 0, base != 0 6996 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6997 match(Set dst (EncodeP src)); 6998 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6999 Universe::narrow_oop_shift() != 0 && 7000 Universe::narrow_oop_base_overlaps()); 7001 7002 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7003 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7004 %} 7005 7006 // shift != 0, base == 0 7007 // TODO: This is the same as encodeP_shift. Merge! 7008 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7009 match(Set dst (EncodeP src)); 7010 predicate(Universe::narrow_oop_shift() != 0 && 7011 Universe::narrow_oop_base() ==0); 7012 7013 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7014 size(4); 7015 ins_encode %{ 7016 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7017 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7018 %} 7019 ins_pipe(pipe_class_default); 7020 %} 7021 7022 // Compressed OOPs with narrow_oop_shift == 0. 7023 // shift == 0, base == 0 7024 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7025 match(Set dst (EncodeP src)); 7026 predicate(Universe::narrow_oop_shift() == 0); 7027 7028 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7029 // variable size, 0 or 4. 7030 ins_encode %{ 7031 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7032 __ mr_if_needed($dst$$Register, $src$$Register); 7033 %} 7034 ins_pipe(pipe_class_default); 7035 %} 7036 7037 // Decode nodes. 7038 7039 // Shift node for expand. 7040 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7041 // The match rule is needed to make it a 'MachTypeNode'! 7042 match(Set dst (DecodeN src)); 7043 predicate(false); 7044 7045 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7046 size(4); 7047 ins_encode %{ 7048 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7049 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7050 %} 7051 ins_pipe(pipe_class_default); 7052 %} 7053 7054 // Add node for expand. 7055 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7056 // The match rule is needed to make it a 'MachTypeNode'! 7057 match(Set dst (DecodeN src)); 7058 predicate(false); 7059 7060 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7061 ins_encode %{ 7062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7063 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7064 %} 7065 ins_pipe(pipe_class_default); 7066 %} 7067 7068 // conditianal add base for expand 7069 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7070 // The match rule is needed to make it a 'MachTypeNode'! 7071 // NOTICE that the rule is nonsense - we just have to make sure that: 7072 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7073 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7074 match(Set dst (DecodeN (Binary crx src))); 7075 predicate(false); 7076 7077 format %{ "BEQ $crx, done\n\t" 7078 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7079 "done:" %} 7080 ins_encode %{ 7081 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7082 Label done; 7083 __ beq($crx$$CondRegister, done); 7084 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7085 __ bind(done); 7086 %} 7087 ins_pipe(pipe_class_default); 7088 %} 7089 7090 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7091 // The match rule is needed to make it a 'MachTypeNode'! 7092 // NOTICE that the rule is nonsense - we just have to make sure that: 7093 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7094 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7095 match(Set dst (DecodeN (Binary crx src1))); 7096 predicate(false); 7097 7098 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7099 size(4); 7100 ins_encode %{ 7101 // This is a Power7 instruction for which no machine description exists. 7102 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7103 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7104 %} 7105 ins_pipe(pipe_class_default); 7106 %} 7107 7108 // shift != 0, base != 0 7109 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7110 match(Set dst (DecodeN src)); 7111 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7112 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7113 Universe::narrow_oop_shift() != 0 && 7114 Universe::narrow_oop_base() != 0); 7115 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7116 effect(TEMP crx); 7117 7118 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7119 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7120 %} 7121 7122 // shift != 0, base == 0 7123 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7124 match(Set dst (DecodeN src)); 7125 predicate(Universe::narrow_oop_shift() != 0 && 7126 Universe::narrow_oop_base() == 0); 7127 7128 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7129 size(4); 7130 ins_encode %{ 7131 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7132 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7133 %} 7134 ins_pipe(pipe_class_default); 7135 %} 7136 7137 // Optimize DecodeN for disjoint base. 7138 // Shift narrow oop and or it into register that already contains the heap base. 7139 // Base == dst must hold, and is assured by construction in postaloc_expand. 7140 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7141 match(Set dst (DecodeN src)); 7142 effect(TEMP base); 7143 predicate(false); 7144 7145 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7146 size(4); 7147 ins_encode %{ 7148 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7149 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7150 %} 7151 ins_pipe(pipe_class_default); 7152 %} 7153 7154 // Optimize DecodeN for disjoint base. 7155 // This node requires only one cycle on the critical path. 7156 // We must postalloc_expand as we can not express use_def effects where 7157 // the used register is L and the def'ed register P. 7158 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7159 match(Set dst (DecodeN src)); 7160 effect(TEMP_DEF dst); 7161 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7162 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7163 Universe::narrow_oop_base_disjoint()); 7164 ins_cost(DEFAULT_COST); 7165 7166 format %{ "MOV $dst, heapbase \t\n" 7167 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7168 postalloc_expand %{ 7169 loadBaseNode *n1 = new loadBaseNode(); 7170 n1->add_req(NULL); 7171 n1->_opnds[0] = op_dst; 7172 7173 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7174 n2->add_req(n_region, n_src, n1); 7175 n2->_opnds[0] = op_dst; 7176 n2->_opnds[1] = op_src; 7177 n2->_opnds[2] = op_dst; 7178 n2->_bottom_type = _bottom_type; 7179 7180 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7181 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7182 7183 nodes->push(n1); 7184 nodes->push(n2); 7185 %} 7186 %} 7187 7188 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7189 match(Set dst (DecodeN src)); 7190 effect(TEMP_DEF dst, TEMP crx); 7191 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7192 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7193 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7194 ins_cost(3 * DEFAULT_COST); 7195 7196 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7197 postalloc_expand %{ 7198 loadBaseNode *n1 = new loadBaseNode(); 7199 n1->add_req(NULL); 7200 n1->_opnds[0] = op_dst; 7201 7202 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7203 n_compare->add_req(n_region, n_src); 7204 n_compare->_opnds[0] = op_crx; 7205 n_compare->_opnds[1] = op_src; 7206 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7207 7208 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7209 n2->add_req(n_region, n_src, n1); 7210 n2->_opnds[0] = op_dst; 7211 n2->_opnds[1] = op_src; 7212 n2->_opnds[2] = op_dst; 7213 n2->_bottom_type = _bottom_type; 7214 7215 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7216 n_cond_set->add_req(n_region, n_compare, n2); 7217 n_cond_set->_opnds[0] = op_dst; 7218 n_cond_set->_opnds[1] = op_crx; 7219 n_cond_set->_opnds[2] = op_dst; 7220 n_cond_set->_bottom_type = _bottom_type; 7221 7222 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7223 ra_->set_oop(n_cond_set, true); 7224 7225 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7226 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7227 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7228 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7229 7230 nodes->push(n1); 7231 nodes->push(n_compare); 7232 nodes->push(n2); 7233 nodes->push(n_cond_set); 7234 %} 7235 %} 7236 7237 // src != 0, shift != 0, base != 0 7238 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7239 match(Set dst (DecodeN src)); 7240 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7241 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7242 Universe::narrow_oop_shift() != 0 && 7243 Universe::narrow_oop_base() != 0); 7244 ins_cost(2 * DEFAULT_COST); 7245 7246 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7247 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7248 %} 7249 7250 // Compressed OOPs with narrow_oop_shift == 0. 7251 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7252 match(Set dst (DecodeN src)); 7253 predicate(Universe::narrow_oop_shift() == 0); 7254 ins_cost(DEFAULT_COST); 7255 7256 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7257 // variable size, 0 or 4. 7258 ins_encode %{ 7259 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7260 __ mr_if_needed($dst$$Register, $src$$Register); 7261 %} 7262 ins_pipe(pipe_class_default); 7263 %} 7264 7265 // Convert compressed oop into int for vectors alignment masking. 7266 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7267 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7268 predicate(Universe::narrow_oop_shift() == 0); 7269 ins_cost(DEFAULT_COST); 7270 7271 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7272 // variable size, 0 or 4. 7273 ins_encode %{ 7274 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7275 __ mr_if_needed($dst$$Register, $src$$Register); 7276 %} 7277 ins_pipe(pipe_class_default); 7278 %} 7279 7280 // Convert klass pointer into compressed form. 7281 7282 // Nodes for postalloc expand. 7283 7284 // Shift node for expand. 7285 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7286 // The match rule is needed to make it a 'MachTypeNode'! 7287 match(Set dst (EncodePKlass src)); 7288 predicate(false); 7289 7290 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7291 size(4); 7292 ins_encode %{ 7293 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7294 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7295 %} 7296 ins_pipe(pipe_class_default); 7297 %} 7298 7299 // Add node for expand. 7300 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7301 // The match rule is needed to make it a 'MachTypeNode'! 7302 match(Set dst (EncodePKlass (Binary base src))); 7303 predicate(false); 7304 7305 format %{ "SUB $dst, $base, $src \t// encode" %} 7306 size(4); 7307 ins_encode %{ 7308 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7309 __ subf($dst$$Register, $base$$Register, $src$$Register); 7310 %} 7311 ins_pipe(pipe_class_default); 7312 %} 7313 7314 // Disjoint narrow oop base. 7315 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7316 match(Set dst (EncodePKlass src)); 7317 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7318 7319 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7320 size(4); 7321 ins_encode %{ 7322 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7323 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7324 %} 7325 ins_pipe(pipe_class_default); 7326 %} 7327 7328 // shift != 0, base != 0 7329 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7330 match(Set dst (EncodePKlass (Binary base src))); 7331 predicate(false); 7332 7333 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7334 postalloc_expand %{ 7335 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7336 n1->add_req(n_region, n_base, n_src); 7337 n1->_opnds[0] = op_dst; 7338 n1->_opnds[1] = op_base; 7339 n1->_opnds[2] = op_src; 7340 n1->_bottom_type = _bottom_type; 7341 7342 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7343 n2->add_req(n_region, n1); 7344 n2->_opnds[0] = op_dst; 7345 n2->_opnds[1] = op_dst; 7346 n2->_bottom_type = _bottom_type; 7347 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7348 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7349 7350 nodes->push(n1); 7351 nodes->push(n2); 7352 %} 7353 %} 7354 7355 // shift != 0, base != 0 7356 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7357 match(Set dst (EncodePKlass src)); 7358 //predicate(Universe::narrow_klass_shift() != 0 && 7359 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7360 7361 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7362 ins_cost(DEFAULT_COST*2); // Don't count constant. 7363 expand %{ 7364 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7365 iRegLdst base; 7366 loadConL_Ex(base, baseImm); 7367 encodePKlass_not_null_Ex(dst, base, src); 7368 %} 7369 %} 7370 7371 // Decode nodes. 7372 7373 // Shift node for expand. 7374 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7375 // The match rule is needed to make it a 'MachTypeNode'! 7376 match(Set dst (DecodeNKlass src)); 7377 predicate(false); 7378 7379 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7380 size(4); 7381 ins_encode %{ 7382 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7383 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7384 %} 7385 ins_pipe(pipe_class_default); 7386 %} 7387 7388 // Add node for expand. 7389 7390 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7391 // The match rule is needed to make it a 'MachTypeNode'! 7392 match(Set dst (DecodeNKlass (Binary base src))); 7393 predicate(false); 7394 7395 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7396 size(4); 7397 ins_encode %{ 7398 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7399 __ add($dst$$Register, $base$$Register, $src$$Register); 7400 %} 7401 ins_pipe(pipe_class_default); 7402 %} 7403 7404 // src != 0, shift != 0, base != 0 7405 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7406 match(Set dst (DecodeNKlass (Binary base src))); 7407 //effect(kill src); // We need a register for the immediate result after shifting. 7408 predicate(false); 7409 7410 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7411 postalloc_expand %{ 7412 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7413 n1->add_req(n_region, n_base, n_src); 7414 n1->_opnds[0] = op_dst; 7415 n1->_opnds[1] = op_base; 7416 n1->_opnds[2] = op_src; 7417 n1->_bottom_type = _bottom_type; 7418 7419 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7420 n2->add_req(n_region, n1); 7421 n2->_opnds[0] = op_dst; 7422 n2->_opnds[1] = op_dst; 7423 n2->_bottom_type = _bottom_type; 7424 7425 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7426 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7427 7428 nodes->push(n1); 7429 nodes->push(n2); 7430 %} 7431 %} 7432 7433 // src != 0, shift != 0, base != 0 7434 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7435 match(Set dst (DecodeNKlass src)); 7436 // predicate(Universe::narrow_klass_shift() != 0 && 7437 // Universe::narrow_klass_base() != 0); 7438 7439 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7440 7441 ins_cost(DEFAULT_COST*2); // Don't count constant. 7442 expand %{ 7443 // We add first, then we shift. Like this, we can get along with one register less. 7444 // But we have to load the base pre-shifted. 7445 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7446 iRegLdst base; 7447 loadConL_Ex(base, baseImm); 7448 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7449 %} 7450 %} 7451 7452 //----------MemBar Instructions----------------------------------------------- 7453 // Memory barrier flavors 7454 7455 instruct membar_acquire() %{ 7456 match(LoadFence); 7457 ins_cost(4*MEMORY_REF_COST); 7458 7459 format %{ "MEMBAR-acquire" %} 7460 size(4); 7461 ins_encode %{ 7462 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7463 __ acquire(); 7464 %} 7465 ins_pipe(pipe_class_default); 7466 %} 7467 7468 instruct unnecessary_membar_acquire() %{ 7469 match(MemBarAcquire); 7470 ins_cost(0); 7471 7472 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7473 size(0); 7474 ins_encode( /*empty*/ ); 7475 ins_pipe(pipe_class_default); 7476 %} 7477 7478 instruct membar_acquire_lock() %{ 7479 match(MemBarAcquireLock); 7480 ins_cost(0); 7481 7482 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7483 size(0); 7484 ins_encode( /*empty*/ ); 7485 ins_pipe(pipe_class_default); 7486 %} 7487 7488 instruct membar_release() %{ 7489 match(MemBarRelease); 7490 match(StoreFence); 7491 ins_cost(4*MEMORY_REF_COST); 7492 7493 format %{ "MEMBAR-release" %} 7494 size(4); 7495 ins_encode %{ 7496 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7497 __ release(); 7498 %} 7499 ins_pipe(pipe_class_default); 7500 %} 7501 7502 instruct membar_storestore() %{ 7503 match(MemBarStoreStore); 7504 ins_cost(4*MEMORY_REF_COST); 7505 7506 format %{ "MEMBAR-store-store" %} 7507 size(4); 7508 ins_encode %{ 7509 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7510 __ membar(Assembler::StoreStore); 7511 %} 7512 ins_pipe(pipe_class_default); 7513 %} 7514 7515 instruct membar_release_lock() %{ 7516 match(MemBarReleaseLock); 7517 ins_cost(0); 7518 7519 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7520 size(0); 7521 ins_encode( /*empty*/ ); 7522 ins_pipe(pipe_class_default); 7523 %} 7524 7525 instruct membar_volatile() %{ 7526 match(MemBarVolatile); 7527 ins_cost(4*MEMORY_REF_COST); 7528 7529 format %{ "MEMBAR-volatile" %} 7530 size(4); 7531 ins_encode %{ 7532 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7533 __ fence(); 7534 %} 7535 ins_pipe(pipe_class_default); 7536 %} 7537 7538 // This optimization is wrong on PPC. The following pattern is not supported: 7539 // MemBarVolatile 7540 // ^ ^ 7541 // | | 7542 // CtrlProj MemProj 7543 // ^ ^ 7544 // | | 7545 // | Load 7546 // | 7547 // MemBarVolatile 7548 // 7549 // The first MemBarVolatile could get optimized out! According to 7550 // Vladimir, this pattern can not occur on Oracle platforms. 7551 // However, it does occur on PPC64 (because of membars in 7552 // inline_unsafe_load_store). 7553 // 7554 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7555 // Don't forget to look at the implementation of post_store_load_barrier again, 7556 // we did other fixes in that method. 7557 //instruct unnecessary_membar_volatile() %{ 7558 // match(MemBarVolatile); 7559 // predicate(Matcher::post_store_load_barrier(n)); 7560 // ins_cost(0); 7561 // 7562 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7563 // size(0); 7564 // ins_encode( /*empty*/ ); 7565 // ins_pipe(pipe_class_default); 7566 //%} 7567 7568 instruct membar_CPUOrder() %{ 7569 match(MemBarCPUOrder); 7570 ins_cost(0); 7571 7572 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7573 size(0); 7574 ins_encode( /*empty*/ ); 7575 ins_pipe(pipe_class_default); 7576 %} 7577 7578 //----------Conditional Move--------------------------------------------------- 7579 7580 // Cmove using isel. 7581 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7582 match(Set dst (CMoveI (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 cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7600 match(Set dst (CMoveI (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 cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7614 match(Set dst (CMoveI (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 cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7628 match(Set dst (CMoveL (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 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7646 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7647 predicate(!VM_Version::has_isel()); 7648 ins_cost(DEFAULT_COST+BRANCH_COST); 7649 7650 ins_variable_size_depending_on_alignment(true); 7651 7652 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7653 // Worst case is branch + move + stop, no stop without scheduler. 7654 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7655 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7656 ins_pipe(pipe_class_default); 7657 %} 7658 7659 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7660 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7661 ins_cost(DEFAULT_COST+BRANCH_COST); 7662 7663 ins_variable_size_depending_on_alignment(true); 7664 7665 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7666 // Worst case is branch + move + stop, no stop without scheduler. 7667 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7668 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7669 ins_pipe(pipe_class_default); 7670 %} 7671 7672 // Cmove using isel. 7673 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7674 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7675 predicate(VM_Version::has_isel()); 7676 ins_cost(DEFAULT_COST); 7677 7678 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7679 size(4); 7680 ins_encode %{ 7681 // This is a Power7 instruction for which no machine description 7682 // exists. Anyways, the scheduler should be off on Power7. 7683 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7684 int cc = $cmp$$cmpcode; 7685 __ isel($dst$$Register, $crx$$CondRegister, 7686 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7687 %} 7688 ins_pipe(pipe_class_default); 7689 %} 7690 7691 // Conditional move for RegN. Only cmov(reg, reg). 7692 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7693 match(Set dst (CMoveN (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 cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7707 match(Set dst (CMoveN (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 // Cmove using isel. 7720 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7721 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7722 predicate(VM_Version::has_isel()); 7723 ins_cost(DEFAULT_COST); 7724 7725 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7726 size(4); 7727 ins_encode %{ 7728 // This is a Power7 instruction for which no machine description 7729 // exists. Anyways, the scheduler should be off on Power7. 7730 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7731 int cc = $cmp$$cmpcode; 7732 __ isel($dst$$Register, $crx$$CondRegister, 7733 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7734 %} 7735 ins_pipe(pipe_class_default); 7736 %} 7737 7738 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7739 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7740 predicate(!VM_Version::has_isel()); 7741 ins_cost(DEFAULT_COST+BRANCH_COST); 7742 7743 ins_variable_size_depending_on_alignment(true); 7744 7745 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7746 // Worst case is branch + move + stop, no stop without scheduler. 7747 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7748 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7749 ins_pipe(pipe_class_default); 7750 %} 7751 7752 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7753 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7754 ins_cost(DEFAULT_COST+BRANCH_COST); 7755 7756 ins_variable_size_depending_on_alignment(true); 7757 7758 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7759 // Worst case is branch + move + stop, no stop without scheduler. 7760 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7761 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7762 ins_pipe(pipe_class_default); 7763 %} 7764 7765 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7766 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7767 ins_cost(DEFAULT_COST+BRANCH_COST); 7768 7769 ins_variable_size_depending_on_alignment(true); 7770 7771 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7772 // Worst case is branch + move + stop, no stop without scheduler. 7773 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7774 ins_encode %{ 7775 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7776 Label done; 7777 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7778 // Branch if not (cmp crx). 7779 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7780 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7781 // TODO PPC port __ endgroup_if_needed(_size == 12); 7782 __ bind(done); 7783 %} 7784 ins_pipe(pipe_class_default); 7785 %} 7786 7787 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7788 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7789 ins_cost(DEFAULT_COST+BRANCH_COST); 7790 7791 ins_variable_size_depending_on_alignment(true); 7792 7793 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7794 // Worst case is branch + move + stop, no stop without scheduler. 7795 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7796 ins_encode %{ 7797 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7798 Label done; 7799 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7800 // Branch if not (cmp crx). 7801 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7802 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7803 // TODO PPC port __ endgroup_if_needed(_size == 12); 7804 __ bind(done); 7805 %} 7806 ins_pipe(pipe_class_default); 7807 %} 7808 7809 //----------Conditional_store-------------------------------------------------- 7810 // Conditional-store of the updated heap-top. 7811 // Used during allocation of the shared heap. 7812 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7813 7814 // As compareAndSwapL, but return flag register instead of boolean value in 7815 // int register. 7816 // Used by sun/misc/AtomicLongCSImpl.java. 7817 // Mem_ptr must be a memory operand, else this node does not get 7818 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7819 // can be rematerialized which leads to errors. 7820 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7821 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7822 effect(TEMP cr0); 7823 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7824 ins_encode %{ 7825 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7826 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7827 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7828 noreg, NULL, true); 7829 %} 7830 ins_pipe(pipe_class_default); 7831 %} 7832 7833 // As compareAndSwapP, but return flag register instead of boolean value in 7834 // int register. 7835 // This instruction is matched if UseTLAB is off. 7836 // Mem_ptr must be a memory operand, else this node does not get 7837 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7838 // can be rematerialized which leads to errors. 7839 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7840 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7841 ins_cost(2*MEMORY_REF_COST); 7842 7843 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7844 ins_encode %{ 7845 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7846 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7847 %} 7848 ins_pipe(pipe_class_memory); 7849 %} 7850 7851 // Implement LoadPLocked. Must be ordered against changes of the memory location 7852 // by storePConditional. 7853 // Don't know whether this is ever used. 7854 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7855 match(Set dst (LoadPLocked mem)); 7856 ins_cost(2*MEMORY_REF_COST); 7857 7858 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7859 size(4); 7860 ins_encode %{ 7861 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7862 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7863 %} 7864 ins_pipe(pipe_class_memory); 7865 %} 7866 7867 //----------Compare-And-Swap--------------------------------------------------- 7868 7869 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7870 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7871 // matched. 7872 7873 // Strong versions: 7874 7875 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7876 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7877 predicate(VM_Version::has_lqarx()); 7878 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7879 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7880 ins_encode %{ 7881 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7882 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7883 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7884 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7885 $res$$Register, true); 7886 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7887 __ isync(); 7888 } else { 7889 __ sync(); 7890 } 7891 %} 7892 ins_pipe(pipe_class_default); 7893 %} 7894 7895 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7896 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7897 predicate(!VM_Version::has_lqarx()); 7898 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7899 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7900 ins_encode %{ 7901 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7902 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7903 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7904 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7905 $res$$Register, true); 7906 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7907 __ isync(); 7908 } else { 7909 __ sync(); 7910 } 7911 %} 7912 ins_pipe(pipe_class_default); 7913 %} 7914 7915 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7916 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7917 predicate(VM_Version::has_lqarx()); 7918 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7919 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7920 ins_encode %{ 7921 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7922 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7923 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7924 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7925 $res$$Register, true); 7926 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7927 __ isync(); 7928 } else { 7929 __ sync(); 7930 } 7931 %} 7932 ins_pipe(pipe_class_default); 7933 %} 7934 7935 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7936 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7937 predicate(!VM_Version::has_lqarx()); 7938 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7939 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7940 ins_encode %{ 7941 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7942 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7943 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7944 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7945 $res$$Register, true); 7946 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7947 __ isync(); 7948 } else { 7949 __ sync(); 7950 } 7951 %} 7952 ins_pipe(pipe_class_default); 7953 %} 7954 7955 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7956 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7957 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7958 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7959 ins_encode %{ 7960 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7961 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7962 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7963 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7964 $res$$Register, true); 7965 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7966 __ isync(); 7967 } else { 7968 __ sync(); 7969 } 7970 %} 7971 ins_pipe(pipe_class_default); 7972 %} 7973 7974 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7975 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7976 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7977 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7978 ins_encode %{ 7979 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7980 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7981 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7982 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7983 $res$$Register, true); 7984 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7985 __ isync(); 7986 } else { 7987 __ sync(); 7988 } 7989 %} 7990 ins_pipe(pipe_class_default); 7991 %} 7992 7993 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7994 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7995 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7996 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7997 ins_encode %{ 7998 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7999 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8000 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8001 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8002 $res$$Register, NULL, true); 8003 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8004 __ isync(); 8005 } else { 8006 __ sync(); 8007 } 8008 %} 8009 ins_pipe(pipe_class_default); 8010 %} 8011 8012 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8013 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8014 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8015 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8016 ins_encode %{ 8017 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8018 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8019 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8020 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8021 $res$$Register, NULL, true); 8022 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8023 __ isync(); 8024 } else { 8025 __ sync(); 8026 } 8027 %} 8028 ins_pipe(pipe_class_default); 8029 %} 8030 8031 // Weak versions: 8032 8033 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8034 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8035 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8036 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8037 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8038 ins_encode %{ 8039 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8040 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8041 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8042 MacroAssembler::MemBarNone, 8043 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8044 %} 8045 ins_pipe(pipe_class_default); 8046 %} 8047 8048 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8049 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8050 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8051 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8052 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8053 ins_encode %{ 8054 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8056 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8057 MacroAssembler::MemBarNone, 8058 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8059 %} 8060 ins_pipe(pipe_class_default); 8061 %} 8062 8063 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8065 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8066 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8067 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8068 ins_encode %{ 8069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8070 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8071 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8072 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8073 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8074 %} 8075 ins_pipe(pipe_class_default); 8076 %} 8077 8078 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8079 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8080 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8081 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8082 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8083 ins_encode %{ 8084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8085 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8086 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8087 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8088 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8089 %} 8090 ins_pipe(pipe_class_default); 8091 %} 8092 8093 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8094 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8095 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8096 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8097 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8098 ins_encode %{ 8099 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8100 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8101 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8102 MacroAssembler::MemBarNone, 8103 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8104 %} 8105 ins_pipe(pipe_class_default); 8106 %} 8107 8108 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8109 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8110 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8111 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8112 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8113 ins_encode %{ 8114 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8115 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8116 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8117 MacroAssembler::MemBarNone, 8118 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8119 %} 8120 ins_pipe(pipe_class_default); 8121 %} 8122 8123 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8124 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8125 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8126 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8127 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8128 ins_encode %{ 8129 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8130 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8131 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8132 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8133 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8134 %} 8135 ins_pipe(pipe_class_default); 8136 %} 8137 8138 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8139 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8140 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8141 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8142 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8143 ins_encode %{ 8144 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8145 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8146 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8147 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8148 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8149 %} 8150 ins_pipe(pipe_class_default); 8151 %} 8152 8153 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8154 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8155 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8156 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8157 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8158 ins_encode %{ 8159 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8160 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8161 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8162 MacroAssembler::MemBarNone, 8163 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8164 %} 8165 ins_pipe(pipe_class_default); 8166 %} 8167 8168 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8169 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8170 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8171 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8172 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8173 ins_encode %{ 8174 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8175 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8176 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8177 // value is never passed to caller. 8178 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8179 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8180 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8181 %} 8182 ins_pipe(pipe_class_default); 8183 %} 8184 8185 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8186 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8187 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8188 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8189 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8190 ins_encode %{ 8191 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8192 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8193 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8194 MacroAssembler::MemBarNone, 8195 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8196 %} 8197 ins_pipe(pipe_class_default); 8198 %} 8199 8200 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8201 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8202 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8203 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8204 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8205 ins_encode %{ 8206 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8207 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8208 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8209 // value is never passed to caller. 8210 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8211 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8212 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8213 %} 8214 ins_pipe(pipe_class_default); 8215 %} 8216 8217 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8218 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8219 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8220 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8221 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8222 ins_encode %{ 8223 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8224 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8225 // value is never passed to caller. 8226 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8227 MacroAssembler::MemBarNone, 8228 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8229 %} 8230 ins_pipe(pipe_class_default); 8231 %} 8232 8233 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8234 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8235 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8236 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8237 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8238 ins_encode %{ 8239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8240 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8241 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8242 // value is never passed to caller. 8243 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8244 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8245 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8246 %} 8247 ins_pipe(pipe_class_default); 8248 %} 8249 8250 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8251 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8252 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8253 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8254 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8255 ins_encode %{ 8256 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8257 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8258 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8259 MacroAssembler::MemBarNone, 8260 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8261 %} 8262 ins_pipe(pipe_class_default); 8263 %} 8264 8265 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8266 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8267 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8268 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8269 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8270 ins_encode %{ 8271 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8272 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8273 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8274 // value is never passed to caller. 8275 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8276 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8277 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8278 %} 8279 ins_pipe(pipe_class_default); 8280 %} 8281 8282 // CompareAndExchange 8283 8284 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8285 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8286 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8287 effect(TEMP_DEF res, TEMP cr0); 8288 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8289 ins_encode %{ 8290 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8291 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8292 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8293 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8294 noreg, true); 8295 %} 8296 ins_pipe(pipe_class_default); 8297 %} 8298 8299 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8300 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8301 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8302 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8303 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8304 ins_encode %{ 8305 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8306 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8307 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8308 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8309 noreg, true); 8310 %} 8311 ins_pipe(pipe_class_default); 8312 %} 8313 8314 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8315 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8316 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8317 effect(TEMP_DEF res, TEMP cr0); 8318 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8319 ins_encode %{ 8320 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8321 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8322 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8323 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8324 noreg, true); 8325 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8326 __ isync(); 8327 } else { 8328 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8329 __ sync(); 8330 } 8331 %} 8332 ins_pipe(pipe_class_default); 8333 %} 8334 8335 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8336 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8337 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8338 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8339 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8340 ins_encode %{ 8341 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8342 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8343 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8344 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8345 noreg, true); 8346 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8347 __ isync(); 8348 } else { 8349 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8350 __ sync(); 8351 } 8352 %} 8353 ins_pipe(pipe_class_default); 8354 %} 8355 8356 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8357 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8358 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8359 effect(TEMP_DEF res, TEMP cr0); 8360 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8361 ins_encode %{ 8362 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8363 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8364 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8365 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8366 noreg, true); 8367 %} 8368 ins_pipe(pipe_class_default); 8369 %} 8370 8371 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8372 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8373 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8374 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8375 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8376 ins_encode %{ 8377 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8378 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8379 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8380 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8381 noreg, true); 8382 %} 8383 ins_pipe(pipe_class_default); 8384 %} 8385 8386 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8387 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8388 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8389 effect(TEMP_DEF res, TEMP cr0); 8390 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8391 ins_encode %{ 8392 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8393 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8394 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8395 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8396 noreg, true); 8397 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8398 __ isync(); 8399 } else { 8400 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8401 __ sync(); 8402 } 8403 %} 8404 ins_pipe(pipe_class_default); 8405 %} 8406 8407 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8408 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8409 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8410 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8411 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8412 ins_encode %{ 8413 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8414 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8415 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8416 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8417 noreg, true); 8418 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8419 __ isync(); 8420 } else { 8421 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8422 __ sync(); 8423 } 8424 %} 8425 ins_pipe(pipe_class_default); 8426 %} 8427 8428 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8429 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8430 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8431 effect(TEMP_DEF res, TEMP cr0); 8432 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8433 ins_encode %{ 8434 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8435 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8436 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8437 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8438 noreg, true); 8439 %} 8440 ins_pipe(pipe_class_default); 8441 %} 8442 8443 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8444 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8445 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8446 effect(TEMP_DEF res, TEMP cr0); 8447 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8448 ins_encode %{ 8449 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8450 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8451 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8452 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8453 noreg, true); 8454 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8455 __ isync(); 8456 } else { 8457 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8458 __ sync(); 8459 } 8460 %} 8461 ins_pipe(pipe_class_default); 8462 %} 8463 8464 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8465 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8466 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8467 effect(TEMP_DEF res, TEMP cr0); 8468 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8469 ins_encode %{ 8470 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8471 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8472 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8473 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8474 noreg, true); 8475 %} 8476 ins_pipe(pipe_class_default); 8477 %} 8478 8479 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8480 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8481 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8482 effect(TEMP_DEF res, TEMP cr0); 8483 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8484 ins_encode %{ 8485 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8486 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8487 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8488 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8489 noreg, true); 8490 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8491 __ isync(); 8492 } else { 8493 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8494 __ sync(); 8495 } 8496 %} 8497 ins_pipe(pipe_class_default); 8498 %} 8499 8500 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8501 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8502 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8503 effect(TEMP_DEF res, TEMP cr0); 8504 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8505 ins_encode %{ 8506 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8507 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8508 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8509 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8510 noreg, NULL, true); 8511 %} 8512 ins_pipe(pipe_class_default); 8513 %} 8514 8515 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8516 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8517 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8518 effect(TEMP_DEF res, TEMP cr0); 8519 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8520 ins_encode %{ 8521 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8522 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8523 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8524 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8525 noreg, NULL, true); 8526 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8527 __ isync(); 8528 } else { 8529 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8530 __ sync(); 8531 } 8532 %} 8533 ins_pipe(pipe_class_default); 8534 %} 8535 8536 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8537 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8538 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8539 effect(TEMP_DEF res, TEMP cr0); 8540 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8541 ins_encode %{ 8542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8544 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8546 noreg, NULL, true); 8547 %} 8548 ins_pipe(pipe_class_default); 8549 %} 8550 8551 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8552 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8553 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8554 effect(TEMP_DEF res, TEMP cr0); 8555 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8556 ins_encode %{ 8557 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8558 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8559 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8560 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8561 noreg, NULL, true); 8562 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8563 __ isync(); 8564 } else { 8565 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8566 __ sync(); 8567 } 8568 %} 8569 ins_pipe(pipe_class_default); 8570 %} 8571 8572 // Special RMW 8573 8574 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8575 match(Set res (GetAndAddB mem_ptr src)); 8576 predicate(VM_Version::has_lqarx()); 8577 effect(TEMP_DEF res, TEMP cr0); 8578 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8579 ins_encode %{ 8580 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8581 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8582 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8583 __ isync(); 8584 } else { 8585 __ sync(); 8586 } 8587 %} 8588 ins_pipe(pipe_class_default); 8589 %} 8590 8591 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8592 match(Set res (GetAndAddB mem_ptr src)); 8593 predicate(!VM_Version::has_lqarx()); 8594 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8595 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8596 ins_encode %{ 8597 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8598 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8599 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8600 __ isync(); 8601 } else { 8602 __ sync(); 8603 } 8604 %} 8605 ins_pipe(pipe_class_default); 8606 %} 8607 8608 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8609 match(Set res (GetAndAddS mem_ptr src)); 8610 predicate(VM_Version::has_lqarx()); 8611 effect(TEMP_DEF res, TEMP cr0); 8612 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8613 ins_encode %{ 8614 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8615 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8616 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8617 __ isync(); 8618 } else { 8619 __ sync(); 8620 } 8621 %} 8622 ins_pipe(pipe_class_default); 8623 %} 8624 8625 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8626 match(Set res (GetAndAddS mem_ptr src)); 8627 predicate(!VM_Version::has_lqarx()); 8628 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8629 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8630 ins_encode %{ 8631 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8632 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8633 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8634 __ isync(); 8635 } else { 8636 __ sync(); 8637 } 8638 %} 8639 ins_pipe(pipe_class_default); 8640 %} 8641 8642 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8643 match(Set res (GetAndAddI mem_ptr src)); 8644 effect(TEMP_DEF res, TEMP cr0); 8645 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8646 ins_encode %{ 8647 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8648 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8649 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8650 __ isync(); 8651 } else { 8652 __ sync(); 8653 } 8654 %} 8655 ins_pipe(pipe_class_default); 8656 %} 8657 8658 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8659 match(Set res (GetAndAddL mem_ptr src)); 8660 effect(TEMP_DEF res, TEMP cr0); 8661 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8662 ins_encode %{ 8663 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8664 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8665 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8666 __ isync(); 8667 } else { 8668 __ sync(); 8669 } 8670 %} 8671 ins_pipe(pipe_class_default); 8672 %} 8673 8674 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8675 match(Set res (GetAndSetB mem_ptr src)); 8676 predicate(VM_Version::has_lqarx()); 8677 effect(TEMP_DEF res, TEMP cr0); 8678 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8679 ins_encode %{ 8680 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8681 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8682 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8683 __ isync(); 8684 } else { 8685 __ sync(); 8686 } 8687 %} 8688 ins_pipe(pipe_class_default); 8689 %} 8690 8691 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8692 match(Set res (GetAndSetB mem_ptr src)); 8693 predicate(!VM_Version::has_lqarx()); 8694 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8695 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8696 ins_encode %{ 8697 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8698 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8699 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8700 __ isync(); 8701 } else { 8702 __ sync(); 8703 } 8704 %} 8705 ins_pipe(pipe_class_default); 8706 %} 8707 8708 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8709 match(Set res (GetAndSetS mem_ptr src)); 8710 predicate(VM_Version::has_lqarx()); 8711 effect(TEMP_DEF res, TEMP cr0); 8712 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8713 ins_encode %{ 8714 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8715 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8716 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8717 __ isync(); 8718 } else { 8719 __ sync(); 8720 } 8721 %} 8722 ins_pipe(pipe_class_default); 8723 %} 8724 8725 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8726 match(Set res (GetAndSetS mem_ptr src)); 8727 predicate(!VM_Version::has_lqarx()); 8728 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8729 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8730 ins_encode %{ 8731 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8732 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8733 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8734 __ isync(); 8735 } else { 8736 __ sync(); 8737 } 8738 %} 8739 ins_pipe(pipe_class_default); 8740 %} 8741 8742 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8743 match(Set res (GetAndSetI mem_ptr src)); 8744 effect(TEMP_DEF res, TEMP cr0); 8745 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8746 ins_encode %{ 8747 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8748 MacroAssembler::cmpxchgx_hint_atomic_update()); 8749 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8750 __ isync(); 8751 } else { 8752 __ sync(); 8753 } 8754 %} 8755 ins_pipe(pipe_class_default); 8756 %} 8757 8758 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8759 match(Set res (GetAndSetL mem_ptr src)); 8760 effect(TEMP_DEF res, TEMP cr0); 8761 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8762 ins_encode %{ 8763 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8764 MacroAssembler::cmpxchgx_hint_atomic_update()); 8765 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8766 __ isync(); 8767 } else { 8768 __ sync(); 8769 } 8770 %} 8771 ins_pipe(pipe_class_default); 8772 %} 8773 8774 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8775 match(Set res (GetAndSetP mem_ptr src)); 8776 effect(TEMP_DEF res, TEMP cr0); 8777 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8778 ins_encode %{ 8779 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8780 MacroAssembler::cmpxchgx_hint_atomic_update()); 8781 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8782 __ isync(); 8783 } else { 8784 __ sync(); 8785 } 8786 %} 8787 ins_pipe(pipe_class_default); 8788 %} 8789 8790 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8791 match(Set res (GetAndSetN mem_ptr src)); 8792 effect(TEMP_DEF res, TEMP cr0); 8793 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8794 ins_encode %{ 8795 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8796 MacroAssembler::cmpxchgx_hint_atomic_update()); 8797 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8798 __ isync(); 8799 } else { 8800 __ sync(); 8801 } 8802 %} 8803 ins_pipe(pipe_class_default); 8804 %} 8805 8806 //----------Arithmetic Instructions-------------------------------------------- 8807 // Addition Instructions 8808 8809 // Register Addition 8810 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8811 match(Set dst (AddI src1 src2)); 8812 format %{ "ADD $dst, $src1, $src2" %} 8813 size(4); 8814 ins_encode %{ 8815 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8816 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8817 %} 8818 ins_pipe(pipe_class_default); 8819 %} 8820 8821 // Expand does not work with above instruct. (??) 8822 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8823 // no match-rule 8824 effect(DEF dst, USE src1, USE src2); 8825 format %{ "ADD $dst, $src1, $src2" %} 8826 size(4); 8827 ins_encode %{ 8828 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8829 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8830 %} 8831 ins_pipe(pipe_class_default); 8832 %} 8833 8834 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8835 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8836 ins_cost(DEFAULT_COST*3); 8837 8838 expand %{ 8839 // FIXME: we should do this in the ideal world. 8840 iRegIdst tmp1; 8841 iRegIdst tmp2; 8842 addI_reg_reg(tmp1, src1, src2); 8843 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8844 addI_reg_reg(dst, tmp1, tmp2); 8845 %} 8846 %} 8847 8848 // Immediate Addition 8849 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8850 match(Set dst (AddI src1 src2)); 8851 format %{ "ADDI $dst, $src1, $src2" %} 8852 size(4); 8853 ins_encode %{ 8854 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8855 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8856 %} 8857 ins_pipe(pipe_class_default); 8858 %} 8859 8860 // Immediate Addition with 16-bit shifted operand 8861 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8862 match(Set dst (AddI src1 src2)); 8863 format %{ "ADDIS $dst, $src1, $src2" %} 8864 size(4); 8865 ins_encode %{ 8866 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8867 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8868 %} 8869 ins_pipe(pipe_class_default); 8870 %} 8871 8872 // Long Addition 8873 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8874 match(Set dst (AddL src1 src2)); 8875 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8876 size(4); 8877 ins_encode %{ 8878 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8879 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8880 %} 8881 ins_pipe(pipe_class_default); 8882 %} 8883 8884 // Expand does not work with above instruct. (??) 8885 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8886 // no match-rule 8887 effect(DEF dst, USE src1, USE src2); 8888 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8889 size(4); 8890 ins_encode %{ 8891 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8892 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8893 %} 8894 ins_pipe(pipe_class_default); 8895 %} 8896 8897 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8898 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8899 ins_cost(DEFAULT_COST*3); 8900 8901 expand %{ 8902 // FIXME: we should do this in the ideal world. 8903 iRegLdst tmp1; 8904 iRegLdst tmp2; 8905 addL_reg_reg(tmp1, src1, src2); 8906 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8907 addL_reg_reg(dst, tmp1, tmp2); 8908 %} 8909 %} 8910 8911 // AddL + ConvL2I. 8912 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8913 match(Set dst (ConvL2I (AddL src1 src2))); 8914 8915 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8916 size(4); 8917 ins_encode %{ 8918 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8919 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8920 %} 8921 ins_pipe(pipe_class_default); 8922 %} 8923 8924 // No constant pool entries required. 8925 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8926 match(Set dst (AddL src1 src2)); 8927 8928 format %{ "ADDI $dst, $src1, $src2" %} 8929 size(4); 8930 ins_encode %{ 8931 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8932 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8933 %} 8934 ins_pipe(pipe_class_default); 8935 %} 8936 8937 // Long Immediate Addition with 16-bit shifted operand. 8938 // No constant pool entries required. 8939 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8940 match(Set dst (AddL src1 src2)); 8941 8942 format %{ "ADDIS $dst, $src1, $src2" %} 8943 size(4); 8944 ins_encode %{ 8945 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8946 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8947 %} 8948 ins_pipe(pipe_class_default); 8949 %} 8950 8951 // Pointer Register Addition 8952 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8953 match(Set dst (AddP src1 src2)); 8954 format %{ "ADD $dst, $src1, $src2" %} 8955 size(4); 8956 ins_encode %{ 8957 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8958 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8959 %} 8960 ins_pipe(pipe_class_default); 8961 %} 8962 8963 // Pointer Immediate Addition 8964 // No constant pool entries required. 8965 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8966 match(Set dst (AddP src1 src2)); 8967 8968 format %{ "ADDI $dst, $src1, $src2" %} 8969 size(4); 8970 ins_encode %{ 8971 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8972 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8973 %} 8974 ins_pipe(pipe_class_default); 8975 %} 8976 8977 // Pointer Immediate Addition with 16-bit shifted operand. 8978 // No constant pool entries required. 8979 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8980 match(Set dst (AddP src1 src2)); 8981 8982 format %{ "ADDIS $dst, $src1, $src2" %} 8983 size(4); 8984 ins_encode %{ 8985 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8986 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8987 %} 8988 ins_pipe(pipe_class_default); 8989 %} 8990 8991 //--------------------- 8992 // Subtraction Instructions 8993 8994 // Register Subtraction 8995 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8996 match(Set dst (SubI src1 src2)); 8997 format %{ "SUBF $dst, $src2, $src1" %} 8998 size(4); 8999 ins_encode %{ 9000 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9001 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9002 %} 9003 ins_pipe(pipe_class_default); 9004 %} 9005 9006 // Immediate Subtraction 9007 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9008 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9009 9010 // SubI from constant (using subfic). 9011 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9012 match(Set dst (SubI src1 src2)); 9013 format %{ "SUBI $dst, $src1, $src2" %} 9014 9015 size(4); 9016 ins_encode %{ 9017 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9018 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9019 %} 9020 ins_pipe(pipe_class_default); 9021 %} 9022 9023 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9024 // positive integers and 0xF...F for negative ones. 9025 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9026 // no match-rule, false predicate 9027 effect(DEF dst, USE src); 9028 predicate(false); 9029 9030 format %{ "SRAWI $dst, $src, #31" %} 9031 size(4); 9032 ins_encode %{ 9033 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9034 __ srawi($dst$$Register, $src$$Register, 0x1f); 9035 %} 9036 ins_pipe(pipe_class_default); 9037 %} 9038 9039 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9040 match(Set dst (AbsI src)); 9041 ins_cost(DEFAULT_COST*3); 9042 9043 expand %{ 9044 iRegIdst tmp1; 9045 iRegIdst tmp2; 9046 signmask32I_regI(tmp1, src); 9047 xorI_reg_reg(tmp2, tmp1, src); 9048 subI_reg_reg(dst, tmp2, tmp1); 9049 %} 9050 %} 9051 9052 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9053 match(Set dst (SubI zero src2)); 9054 format %{ "NEG $dst, $src2" %} 9055 size(4); 9056 ins_encode %{ 9057 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9058 __ neg($dst$$Register, $src2$$Register); 9059 %} 9060 ins_pipe(pipe_class_default); 9061 %} 9062 9063 // Long subtraction 9064 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9065 match(Set dst (SubL src1 src2)); 9066 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9067 size(4); 9068 ins_encode %{ 9069 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9070 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9071 %} 9072 ins_pipe(pipe_class_default); 9073 %} 9074 9075 // SubL + convL2I. 9076 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9077 match(Set dst (ConvL2I (SubL src1 src2))); 9078 9079 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9080 size(4); 9081 ins_encode %{ 9082 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9083 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9084 %} 9085 ins_pipe(pipe_class_default); 9086 %} 9087 9088 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9089 // positive longs and 0xF...F for negative ones. 9090 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9091 // no match-rule, false predicate 9092 effect(DEF dst, USE src); 9093 predicate(false); 9094 9095 format %{ "SRADI $dst, $src, #63" %} 9096 size(4); 9097 ins_encode %{ 9098 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9099 __ sradi($dst$$Register, $src$$Register, 0x3f); 9100 %} 9101 ins_pipe(pipe_class_default); 9102 %} 9103 9104 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9105 // positive longs and 0xF...F for negative ones. 9106 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9107 // no match-rule, false predicate 9108 effect(DEF dst, USE src); 9109 predicate(false); 9110 9111 format %{ "SRADI $dst, $src, #63" %} 9112 size(4); 9113 ins_encode %{ 9114 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9115 __ sradi($dst$$Register, $src$$Register, 0x3f); 9116 %} 9117 ins_pipe(pipe_class_default); 9118 %} 9119 9120 // Long negation 9121 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9122 match(Set dst (SubL zero src2)); 9123 format %{ "NEG $dst, $src2 \t// long" %} 9124 size(4); 9125 ins_encode %{ 9126 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9127 __ neg($dst$$Register, $src2$$Register); 9128 %} 9129 ins_pipe(pipe_class_default); 9130 %} 9131 9132 // NegL + ConvL2I. 9133 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9134 match(Set dst (ConvL2I (SubL zero src2))); 9135 9136 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9137 size(4); 9138 ins_encode %{ 9139 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9140 __ neg($dst$$Register, $src2$$Register); 9141 %} 9142 ins_pipe(pipe_class_default); 9143 %} 9144 9145 // Multiplication Instructions 9146 // Integer Multiplication 9147 9148 // Register Multiplication 9149 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9150 match(Set dst (MulI src1 src2)); 9151 ins_cost(DEFAULT_COST); 9152 9153 format %{ "MULLW $dst, $src1, $src2" %} 9154 size(4); 9155 ins_encode %{ 9156 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9157 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9158 %} 9159 ins_pipe(pipe_class_default); 9160 %} 9161 9162 // Immediate Multiplication 9163 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9164 match(Set dst (MulI src1 src2)); 9165 ins_cost(DEFAULT_COST); 9166 9167 format %{ "MULLI $dst, $src1, $src2" %} 9168 size(4); 9169 ins_encode %{ 9170 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9171 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9172 %} 9173 ins_pipe(pipe_class_default); 9174 %} 9175 9176 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9177 match(Set dst (MulL src1 src2)); 9178 ins_cost(DEFAULT_COST); 9179 9180 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9181 size(4); 9182 ins_encode %{ 9183 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9184 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9185 %} 9186 ins_pipe(pipe_class_default); 9187 %} 9188 9189 // Multiply high for optimized long division by constant. 9190 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9191 match(Set dst (MulHiL src1 src2)); 9192 ins_cost(DEFAULT_COST); 9193 9194 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9198 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9199 %} 9200 ins_pipe(pipe_class_default); 9201 %} 9202 9203 // Immediate Multiplication 9204 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9205 match(Set dst (MulL src1 src2)); 9206 ins_cost(DEFAULT_COST); 9207 9208 format %{ "MULLI $dst, $src1, $src2" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9212 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9213 %} 9214 ins_pipe(pipe_class_default); 9215 %} 9216 9217 // Integer Division with Immediate -1: Negate. 9218 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9219 match(Set dst (DivI src1 src2)); 9220 ins_cost(DEFAULT_COST); 9221 9222 format %{ "NEG $dst, $src1 \t// /-1" %} 9223 size(4); 9224 ins_encode %{ 9225 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9226 __ neg($dst$$Register, $src1$$Register); 9227 %} 9228 ins_pipe(pipe_class_default); 9229 %} 9230 9231 // Integer Division with constant, but not -1. 9232 // We should be able to improve this by checking the type of src2. 9233 // It might well be that src2 is known to be positive. 9234 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9235 match(Set dst (DivI src1 src2)); 9236 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9237 ins_cost(2*DEFAULT_COST); 9238 9239 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9240 size(4); 9241 ins_encode %{ 9242 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9243 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9244 %} 9245 ins_pipe(pipe_class_default); 9246 %} 9247 9248 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9249 effect(USE_DEF dst, USE src1, USE crx); 9250 predicate(false); 9251 9252 ins_variable_size_depending_on_alignment(true); 9253 9254 format %{ "CMOVE $dst, neg($src1), $crx" %} 9255 // Worst case is branch + move + stop, no stop without scheduler. 9256 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9257 ins_encode %{ 9258 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9259 Label done; 9260 __ bne($crx$$CondRegister, done); 9261 __ neg($dst$$Register, $src1$$Register); 9262 // TODO PPC port __ endgroup_if_needed(_size == 12); 9263 __ bind(done); 9264 %} 9265 ins_pipe(pipe_class_default); 9266 %} 9267 9268 // Integer Division with Registers not containing constants. 9269 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9270 match(Set dst (DivI src1 src2)); 9271 ins_cost(10*DEFAULT_COST); 9272 9273 expand %{ 9274 immI16 imm %{ (int)-1 %} 9275 flagsReg tmp1; 9276 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9277 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9278 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9279 %} 9280 %} 9281 9282 // Long Division with Immediate -1: Negate. 9283 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9284 match(Set dst (DivL src1 src2)); 9285 ins_cost(DEFAULT_COST); 9286 9287 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9291 __ neg($dst$$Register, $src1$$Register); 9292 %} 9293 ins_pipe(pipe_class_default); 9294 %} 9295 9296 // Long Division with constant, but not -1. 9297 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9298 match(Set dst (DivL src1 src2)); 9299 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9300 ins_cost(2*DEFAULT_COST); 9301 9302 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9303 size(4); 9304 ins_encode %{ 9305 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9306 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9307 %} 9308 ins_pipe(pipe_class_default); 9309 %} 9310 9311 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9312 effect(USE_DEF dst, USE src1, USE crx); 9313 predicate(false); 9314 9315 ins_variable_size_depending_on_alignment(true); 9316 9317 format %{ "CMOVE $dst, neg($src1), $crx" %} 9318 // Worst case is branch + move + stop, no stop without scheduler. 9319 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9320 ins_encode %{ 9321 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9322 Label done; 9323 __ bne($crx$$CondRegister, done); 9324 __ neg($dst$$Register, $src1$$Register); 9325 // TODO PPC port __ endgroup_if_needed(_size == 12); 9326 __ bind(done); 9327 %} 9328 ins_pipe(pipe_class_default); 9329 %} 9330 9331 // Long Division with Registers not containing constants. 9332 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9333 match(Set dst (DivL src1 src2)); 9334 ins_cost(10*DEFAULT_COST); 9335 9336 expand %{ 9337 immL16 imm %{ (int)-1 %} 9338 flagsReg tmp1; 9339 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9340 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9341 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9342 %} 9343 %} 9344 9345 // Integer Remainder with registers. 9346 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9347 match(Set dst (ModI src1 src2)); 9348 ins_cost(10*DEFAULT_COST); 9349 9350 expand %{ 9351 immI16 imm %{ (int)-1 %} 9352 flagsReg tmp1; 9353 iRegIdst tmp2; 9354 iRegIdst tmp3; 9355 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9356 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9357 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9358 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9359 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9360 %} 9361 %} 9362 9363 // Long Remainder with registers 9364 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9365 match(Set dst (ModL src1 src2)); 9366 ins_cost(10*DEFAULT_COST); 9367 9368 expand %{ 9369 immL16 imm %{ (int)-1 %} 9370 flagsReg tmp1; 9371 iRegLdst tmp2; 9372 iRegLdst tmp3; 9373 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9374 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9375 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9376 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9377 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9378 %} 9379 %} 9380 9381 // Integer Shift Instructions 9382 9383 // Register Shift Left 9384 9385 // Clear all but the lowest #mask bits. 9386 // Used to normalize shift amounts in registers. 9387 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9388 // no match-rule, false predicate 9389 effect(DEF dst, USE src, USE mask); 9390 predicate(false); 9391 9392 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9393 size(4); 9394 ins_encode %{ 9395 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9396 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9397 %} 9398 ins_pipe(pipe_class_default); 9399 %} 9400 9401 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9402 // no match-rule, false predicate 9403 effect(DEF dst, USE src1, USE src2); 9404 predicate(false); 9405 9406 format %{ "SLW $dst, $src1, $src2" %} 9407 size(4); 9408 ins_encode %{ 9409 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9410 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9411 %} 9412 ins_pipe(pipe_class_default); 9413 %} 9414 9415 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9416 match(Set dst (LShiftI src1 src2)); 9417 ins_cost(DEFAULT_COST*2); 9418 expand %{ 9419 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9420 iRegIdst tmpI; 9421 maskI_reg_imm(tmpI, src2, mask); 9422 lShiftI_reg_reg(dst, src1, tmpI); 9423 %} 9424 %} 9425 9426 // Register Shift Left Immediate 9427 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9428 match(Set dst (LShiftI src1 src2)); 9429 9430 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9431 size(4); 9432 ins_encode %{ 9433 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9434 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9435 %} 9436 ins_pipe(pipe_class_default); 9437 %} 9438 9439 // AndI with negpow2-constant + LShiftI 9440 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9441 match(Set dst (LShiftI (AndI src1 src2) src3)); 9442 predicate(UseRotateAndMaskInstructionsPPC64); 9443 9444 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9445 size(4); 9446 ins_encode %{ 9447 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9448 long src2 = $src2$$constant; 9449 long src3 = $src3$$constant; 9450 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9451 if (maskbits >= 32) { 9452 __ li($dst$$Register, 0); // addi 9453 } else { 9454 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9455 } 9456 %} 9457 ins_pipe(pipe_class_default); 9458 %} 9459 9460 // RShiftI + AndI with negpow2-constant + LShiftI 9461 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9462 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9463 predicate(UseRotateAndMaskInstructionsPPC64); 9464 9465 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9466 size(4); 9467 ins_encode %{ 9468 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9469 long src2 = $src2$$constant; 9470 long src3 = $src3$$constant; 9471 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9472 if (maskbits >= 32) { 9473 __ li($dst$$Register, 0); // addi 9474 } else { 9475 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9476 } 9477 %} 9478 ins_pipe(pipe_class_default); 9479 %} 9480 9481 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9482 // no match-rule, false predicate 9483 effect(DEF dst, USE src1, USE src2); 9484 predicate(false); 9485 9486 format %{ "SLD $dst, $src1, $src2" %} 9487 size(4); 9488 ins_encode %{ 9489 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9490 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9491 %} 9492 ins_pipe(pipe_class_default); 9493 %} 9494 9495 // Register Shift Left 9496 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9497 match(Set dst (LShiftL src1 src2)); 9498 ins_cost(DEFAULT_COST*2); 9499 expand %{ 9500 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9501 iRegIdst tmpI; 9502 maskI_reg_imm(tmpI, src2, mask); 9503 lShiftL_regL_regI(dst, src1, tmpI); 9504 %} 9505 %} 9506 9507 // Register Shift Left Immediate 9508 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9509 match(Set dst (LShiftL src1 src2)); 9510 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9511 size(4); 9512 ins_encode %{ 9513 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9514 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9515 %} 9516 ins_pipe(pipe_class_default); 9517 %} 9518 9519 // If we shift more than 32 bits, we need not convert I2L. 9520 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9521 match(Set dst (LShiftL (ConvI2L src1) src2)); 9522 ins_cost(DEFAULT_COST); 9523 9524 size(4); 9525 format %{ "SLDI $dst, i2l($src1), $src2" %} 9526 ins_encode %{ 9527 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9528 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9529 %} 9530 ins_pipe(pipe_class_default); 9531 %} 9532 9533 // Shift a postivie int to the left. 9534 // Clrlsldi clears the upper 32 bits and shifts. 9535 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9536 match(Set dst (LShiftL (ConvI2L src1) src2)); 9537 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9538 9539 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9540 size(4); 9541 ins_encode %{ 9542 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9543 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9544 %} 9545 ins_pipe(pipe_class_default); 9546 %} 9547 9548 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9549 // no match-rule, false predicate 9550 effect(DEF dst, USE src1, USE src2); 9551 predicate(false); 9552 9553 format %{ "SRAW $dst, $src1, $src2" %} 9554 size(4); 9555 ins_encode %{ 9556 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9557 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9558 %} 9559 ins_pipe(pipe_class_default); 9560 %} 9561 9562 // Register Arithmetic Shift Right 9563 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9564 match(Set dst (RShiftI src1 src2)); 9565 ins_cost(DEFAULT_COST*2); 9566 expand %{ 9567 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9568 iRegIdst tmpI; 9569 maskI_reg_imm(tmpI, src2, mask); 9570 arShiftI_reg_reg(dst, src1, tmpI); 9571 %} 9572 %} 9573 9574 // Register Arithmetic Shift Right Immediate 9575 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9576 match(Set dst (RShiftI src1 src2)); 9577 9578 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9579 size(4); 9580 ins_encode %{ 9581 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9582 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9583 %} 9584 ins_pipe(pipe_class_default); 9585 %} 9586 9587 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9588 // no match-rule, false predicate 9589 effect(DEF dst, USE src1, USE src2); 9590 predicate(false); 9591 9592 format %{ "SRAD $dst, $src1, $src2" %} 9593 size(4); 9594 ins_encode %{ 9595 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9596 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9597 %} 9598 ins_pipe(pipe_class_default); 9599 %} 9600 9601 // Register Shift Right Arithmetic Long 9602 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9603 match(Set dst (RShiftL src1 src2)); 9604 ins_cost(DEFAULT_COST*2); 9605 9606 expand %{ 9607 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9608 iRegIdst tmpI; 9609 maskI_reg_imm(tmpI, src2, mask); 9610 arShiftL_regL_regI(dst, src1, tmpI); 9611 %} 9612 %} 9613 9614 // Register Shift Right Immediate 9615 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9616 match(Set dst (RShiftL src1 src2)); 9617 9618 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9619 size(4); 9620 ins_encode %{ 9621 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9622 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9623 %} 9624 ins_pipe(pipe_class_default); 9625 %} 9626 9627 // RShiftL + ConvL2I 9628 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9629 match(Set dst (ConvL2I (RShiftL src1 src2))); 9630 9631 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9632 size(4); 9633 ins_encode %{ 9634 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9635 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9636 %} 9637 ins_pipe(pipe_class_default); 9638 %} 9639 9640 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9641 // no match-rule, false predicate 9642 effect(DEF dst, USE src1, USE src2); 9643 predicate(false); 9644 9645 format %{ "SRW $dst, $src1, $src2" %} 9646 size(4); 9647 ins_encode %{ 9648 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9649 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9650 %} 9651 ins_pipe(pipe_class_default); 9652 %} 9653 9654 // Register Shift Right 9655 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9656 match(Set dst (URShiftI src1 src2)); 9657 ins_cost(DEFAULT_COST*2); 9658 9659 expand %{ 9660 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9661 iRegIdst tmpI; 9662 maskI_reg_imm(tmpI, src2, mask); 9663 urShiftI_reg_reg(dst, src1, tmpI); 9664 %} 9665 %} 9666 9667 // Register Shift Right Immediate 9668 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9669 match(Set dst (URShiftI src1 src2)); 9670 9671 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9672 size(4); 9673 ins_encode %{ 9674 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9675 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9676 %} 9677 ins_pipe(pipe_class_default); 9678 %} 9679 9680 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9681 // no match-rule, false predicate 9682 effect(DEF dst, USE src1, USE src2); 9683 predicate(false); 9684 9685 format %{ "SRD $dst, $src1, $src2" %} 9686 size(4); 9687 ins_encode %{ 9688 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9689 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9690 %} 9691 ins_pipe(pipe_class_default); 9692 %} 9693 9694 // Register Shift Right 9695 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9696 match(Set dst (URShiftL src1 src2)); 9697 ins_cost(DEFAULT_COST*2); 9698 9699 expand %{ 9700 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9701 iRegIdst tmpI; 9702 maskI_reg_imm(tmpI, src2, mask); 9703 urShiftL_regL_regI(dst, src1, tmpI); 9704 %} 9705 %} 9706 9707 // Register Shift Right Immediate 9708 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9709 match(Set dst (URShiftL src1 src2)); 9710 9711 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9712 size(4); 9713 ins_encode %{ 9714 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9715 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9716 %} 9717 ins_pipe(pipe_class_default); 9718 %} 9719 9720 // URShiftL + ConvL2I. 9721 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9722 match(Set dst (ConvL2I (URShiftL src1 src2))); 9723 9724 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9725 size(4); 9726 ins_encode %{ 9727 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9728 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9729 %} 9730 ins_pipe(pipe_class_default); 9731 %} 9732 9733 // Register Shift Right Immediate with a CastP2X 9734 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9735 match(Set dst (URShiftL (CastP2X src1) src2)); 9736 9737 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9738 size(4); 9739 ins_encode %{ 9740 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9741 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9742 %} 9743 ins_pipe(pipe_class_default); 9744 %} 9745 9746 // Bitfield Extract: URShiftI + AndI 9747 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9748 match(Set dst (AndI (URShiftI src1 src2) src3)); 9749 9750 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9751 size(4); 9752 ins_encode %{ 9753 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9754 int rshift = ($src2$$constant) & 0x1f; 9755 int length = log2_long(((jlong) $src3$$constant) + 1); 9756 if (rshift + length > 32) { 9757 // if necessary, adjust mask to omit rotated bits. 9758 length = 32 - rshift; 9759 } 9760 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9761 %} 9762 ins_pipe(pipe_class_default); 9763 %} 9764 9765 // Bitfield Extract: URShiftL + AndL 9766 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9767 match(Set dst (AndL (URShiftL src1 src2) src3)); 9768 9769 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9770 size(4); 9771 ins_encode %{ 9772 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9773 int rshift = ($src2$$constant) & 0x3f; 9774 int length = log2_long(((jlong) $src3$$constant) + 1); 9775 if (rshift + length > 64) { 9776 // if necessary, adjust mask to omit rotated bits. 9777 length = 64 - rshift; 9778 } 9779 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9780 %} 9781 ins_pipe(pipe_class_default); 9782 %} 9783 9784 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9785 match(Set dst (ConvL2I (ConvI2L src))); 9786 9787 format %{ "EXTSW $dst, $src \t// int->int" %} 9788 size(4); 9789 ins_encode %{ 9790 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9791 __ extsw($dst$$Register, $src$$Register); 9792 %} 9793 ins_pipe(pipe_class_default); 9794 %} 9795 9796 //----------Rotate Instructions------------------------------------------------ 9797 9798 // Rotate Left by 8-bit immediate 9799 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9800 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9801 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9802 9803 format %{ "ROTLWI $dst, $src, $lshift" %} 9804 size(4); 9805 ins_encode %{ 9806 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9807 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9808 %} 9809 ins_pipe(pipe_class_default); 9810 %} 9811 9812 // Rotate Right by 8-bit immediate 9813 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9814 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9815 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9816 9817 format %{ "ROTRWI $dst, $rshift" %} 9818 size(4); 9819 ins_encode %{ 9820 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9821 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9822 %} 9823 ins_pipe(pipe_class_default); 9824 %} 9825 9826 //----------Floating Point Arithmetic Instructions----------------------------- 9827 9828 // Add float single precision 9829 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9830 match(Set dst (AddF src1 src2)); 9831 9832 format %{ "FADDS $dst, $src1, $src2" %} 9833 size(4); 9834 ins_encode %{ 9835 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9836 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9837 %} 9838 ins_pipe(pipe_class_default); 9839 %} 9840 9841 // Add float double precision 9842 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9843 match(Set dst (AddD src1 src2)); 9844 9845 format %{ "FADD $dst, $src1, $src2" %} 9846 size(4); 9847 ins_encode %{ 9848 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9849 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9850 %} 9851 ins_pipe(pipe_class_default); 9852 %} 9853 9854 // Sub float single precision 9855 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9856 match(Set dst (SubF src1 src2)); 9857 9858 format %{ "FSUBS $dst, $src1, $src2" %} 9859 size(4); 9860 ins_encode %{ 9861 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9862 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9863 %} 9864 ins_pipe(pipe_class_default); 9865 %} 9866 9867 // Sub float double precision 9868 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9869 match(Set dst (SubD src1 src2)); 9870 format %{ "FSUB $dst, $src1, $src2" %} 9871 size(4); 9872 ins_encode %{ 9873 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9874 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9875 %} 9876 ins_pipe(pipe_class_default); 9877 %} 9878 9879 // Mul float single precision 9880 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9881 match(Set dst (MulF src1 src2)); 9882 format %{ "FMULS $dst, $src1, $src2" %} 9883 size(4); 9884 ins_encode %{ 9885 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9886 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 // Mul float double precision 9892 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9893 match(Set dst (MulD src1 src2)); 9894 format %{ "FMUL $dst, $src1, $src2" %} 9895 size(4); 9896 ins_encode %{ 9897 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9898 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9899 %} 9900 ins_pipe(pipe_class_default); 9901 %} 9902 9903 // Div float single precision 9904 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9905 match(Set dst (DivF src1 src2)); 9906 format %{ "FDIVS $dst, $src1, $src2" %} 9907 size(4); 9908 ins_encode %{ 9909 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9910 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9911 %} 9912 ins_pipe(pipe_class_default); 9913 %} 9914 9915 // Div float double precision 9916 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9917 match(Set dst (DivD src1 src2)); 9918 format %{ "FDIV $dst, $src1, $src2" %} 9919 size(4); 9920 ins_encode %{ 9921 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9922 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9923 %} 9924 ins_pipe(pipe_class_default); 9925 %} 9926 9927 // Absolute float single precision 9928 instruct absF_reg(regF dst, regF src) %{ 9929 match(Set dst (AbsF src)); 9930 format %{ "FABS $dst, $src \t// float" %} 9931 size(4); 9932 ins_encode %{ 9933 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9934 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9935 %} 9936 ins_pipe(pipe_class_default); 9937 %} 9938 9939 // Absolute float double precision 9940 instruct absD_reg(regD dst, regD src) %{ 9941 match(Set dst (AbsD src)); 9942 format %{ "FABS $dst, $src \t// double" %} 9943 size(4); 9944 ins_encode %{ 9945 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9946 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9947 %} 9948 ins_pipe(pipe_class_default); 9949 %} 9950 9951 instruct negF_reg(regF dst, regF src) %{ 9952 match(Set dst (NegF src)); 9953 format %{ "FNEG $dst, $src \t// float" %} 9954 size(4); 9955 ins_encode %{ 9956 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9957 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9958 %} 9959 ins_pipe(pipe_class_default); 9960 %} 9961 9962 instruct negD_reg(regD dst, regD src) %{ 9963 match(Set dst (NegD src)); 9964 format %{ "FNEG $dst, $src \t// double" %} 9965 size(4); 9966 ins_encode %{ 9967 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9968 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9969 %} 9970 ins_pipe(pipe_class_default); 9971 %} 9972 9973 // AbsF + NegF. 9974 instruct negF_absF_reg(regF dst, regF src) %{ 9975 match(Set dst (NegF (AbsF src))); 9976 format %{ "FNABS $dst, $src \t// float" %} 9977 size(4); 9978 ins_encode %{ 9979 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9980 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9981 %} 9982 ins_pipe(pipe_class_default); 9983 %} 9984 9985 // AbsD + NegD. 9986 instruct negD_absD_reg(regD dst, regD src) %{ 9987 match(Set dst (NegD (AbsD src))); 9988 format %{ "FNABS $dst, $src \t// double" %} 9989 size(4); 9990 ins_encode %{ 9991 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9992 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9993 %} 9994 ins_pipe(pipe_class_default); 9995 %} 9996 9997 // VM_Version::has_fsqrt() decides if this node will be used. 9998 // Sqrt float double precision 9999 instruct sqrtD_reg(regD dst, regD src) %{ 10000 match(Set dst (SqrtD src)); 10001 format %{ "FSQRT $dst, $src" %} 10002 size(4); 10003 ins_encode %{ 10004 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10005 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10006 %} 10007 ins_pipe(pipe_class_default); 10008 %} 10009 10010 // Single-precision sqrt. 10011 instruct sqrtF_reg(regF dst, regF src) %{ 10012 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10013 predicate(VM_Version::has_fsqrts()); 10014 ins_cost(DEFAULT_COST); 10015 10016 format %{ "FSQRTS $dst, $src" %} 10017 size(4); 10018 ins_encode %{ 10019 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10020 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10021 %} 10022 ins_pipe(pipe_class_default); 10023 %} 10024 10025 instruct roundDouble_nop(regD dst) %{ 10026 match(Set dst (RoundDouble dst)); 10027 ins_cost(0); 10028 10029 format %{ " -- \t// RoundDouble not needed - empty" %} 10030 size(0); 10031 // PPC results are already "rounded" (i.e., normal-format IEEE). 10032 ins_encode( /*empty*/ ); 10033 ins_pipe(pipe_class_default); 10034 %} 10035 10036 instruct roundFloat_nop(regF dst) %{ 10037 match(Set dst (RoundFloat dst)); 10038 ins_cost(0); 10039 10040 format %{ " -- \t// RoundFloat not needed - empty" %} 10041 size(0); 10042 // PPC results are already "rounded" (i.e., normal-format IEEE). 10043 ins_encode( /*empty*/ ); 10044 ins_pipe(pipe_class_default); 10045 %} 10046 10047 10048 // Multiply-Accumulate 10049 // src1 * src2 + src3 10050 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10051 match(Set dst (FmaF src3 (Binary src1 src2))); 10052 10053 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10054 size(4); 10055 ins_encode %{ 10056 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10057 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10058 %} 10059 ins_pipe(pipe_class_default); 10060 %} 10061 10062 // src1 * src2 + src3 10063 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10064 match(Set dst (FmaD src3 (Binary src1 src2))); 10065 10066 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10067 size(4); 10068 ins_encode %{ 10069 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10070 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10071 %} 10072 ins_pipe(pipe_class_default); 10073 %} 10074 10075 // -src1 * src2 + src3 = -(src1*src2-src3) 10076 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10077 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10078 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10079 10080 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10081 size(4); 10082 ins_encode %{ 10083 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10084 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10085 %} 10086 ins_pipe(pipe_class_default); 10087 %} 10088 10089 // -src1 * src2 + src3 = -(src1*src2-src3) 10090 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10091 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10092 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10093 10094 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10095 size(4); 10096 ins_encode %{ 10097 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10098 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10099 %} 10100 ins_pipe(pipe_class_default); 10101 %} 10102 10103 // -src1 * src2 - src3 = -(src1*src2+src3) 10104 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10105 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10106 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10107 10108 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10109 size(4); 10110 ins_encode %{ 10111 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10112 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10113 %} 10114 ins_pipe(pipe_class_default); 10115 %} 10116 10117 // -src1 * src2 - src3 = -(src1*src2+src3) 10118 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10119 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10120 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10121 10122 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10123 size(4); 10124 ins_encode %{ 10125 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10126 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10127 %} 10128 ins_pipe(pipe_class_default); 10129 %} 10130 10131 // src1 * src2 - src3 10132 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10133 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10134 10135 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10136 size(4); 10137 ins_encode %{ 10138 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10139 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10140 %} 10141 ins_pipe(pipe_class_default); 10142 %} 10143 10144 // src1 * src2 - src3 10145 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10146 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10147 10148 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10149 size(4); 10150 ins_encode %{ 10151 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10152 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10153 %} 10154 ins_pipe(pipe_class_default); 10155 %} 10156 10157 10158 //----------Logical Instructions----------------------------------------------- 10159 10160 // And Instructions 10161 10162 // Register And 10163 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10164 match(Set dst (AndI src1 src2)); 10165 format %{ "AND $dst, $src1, $src2" %} 10166 size(4); 10167 ins_encode %{ 10168 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10169 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10170 %} 10171 ins_pipe(pipe_class_default); 10172 %} 10173 10174 // Left shifted Immediate And 10175 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10176 match(Set dst (AndI src1 src2)); 10177 effect(KILL cr0); 10178 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10179 size(4); 10180 ins_encode %{ 10181 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10182 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10183 %} 10184 ins_pipe(pipe_class_default); 10185 %} 10186 10187 // Immediate And 10188 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10189 match(Set dst (AndI src1 src2)); 10190 effect(KILL cr0); 10191 10192 format %{ "ANDI $dst, $src1, $src2" %} 10193 size(4); 10194 ins_encode %{ 10195 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10196 // FIXME: avoid andi_ ? 10197 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10198 %} 10199 ins_pipe(pipe_class_default); 10200 %} 10201 10202 // Immediate And where the immediate is a negative power of 2. 10203 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10204 match(Set dst (AndI src1 src2)); 10205 format %{ "ANDWI $dst, $src1, $src2" %} 10206 size(4); 10207 ins_encode %{ 10208 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10209 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10210 %} 10211 ins_pipe(pipe_class_default); 10212 %} 10213 10214 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10215 match(Set dst (AndI src1 src2)); 10216 format %{ "ANDWI $dst, $src1, $src2" %} 10217 size(4); 10218 ins_encode %{ 10219 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10220 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10221 %} 10222 ins_pipe(pipe_class_default); 10223 %} 10224 10225 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10226 match(Set dst (AndI src1 src2)); 10227 predicate(UseRotateAndMaskInstructionsPPC64); 10228 format %{ "ANDWI $dst, $src1, $src2" %} 10229 size(4); 10230 ins_encode %{ 10231 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10232 __ rlwinm($dst$$Register, $src1$$Register, 0, 10233 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10234 %} 10235 ins_pipe(pipe_class_default); 10236 %} 10237 10238 // Register And Long 10239 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10240 match(Set dst (AndL src1 src2)); 10241 ins_cost(DEFAULT_COST); 10242 10243 format %{ "AND $dst, $src1, $src2 \t// long" %} 10244 size(4); 10245 ins_encode %{ 10246 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10247 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10248 %} 10249 ins_pipe(pipe_class_default); 10250 %} 10251 10252 // Immediate And long 10253 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10254 match(Set dst (AndL src1 src2)); 10255 effect(KILL cr0); 10256 10257 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10258 size(4); 10259 ins_encode %{ 10260 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10261 // FIXME: avoid andi_ ? 10262 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10263 %} 10264 ins_pipe(pipe_class_default); 10265 %} 10266 10267 // Immediate And Long where the immediate is a negative power of 2. 10268 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10269 match(Set dst (AndL src1 src2)); 10270 format %{ "ANDDI $dst, $src1, $src2" %} 10271 size(4); 10272 ins_encode %{ 10273 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10274 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10275 %} 10276 ins_pipe(pipe_class_default); 10277 %} 10278 10279 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10280 match(Set dst (AndL src1 src2)); 10281 format %{ "ANDDI $dst, $src1, $src2" %} 10282 size(4); 10283 ins_encode %{ 10284 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10285 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10286 %} 10287 ins_pipe(pipe_class_default); 10288 %} 10289 10290 // AndL + ConvL2I. 10291 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10292 match(Set dst (ConvL2I (AndL src1 src2))); 10293 ins_cost(DEFAULT_COST); 10294 10295 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10296 size(4); 10297 ins_encode %{ 10298 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10299 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10300 %} 10301 ins_pipe(pipe_class_default); 10302 %} 10303 10304 // Or Instructions 10305 10306 // Register Or 10307 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10308 match(Set dst (OrI src1 src2)); 10309 format %{ "OR $dst, $src1, $src2" %} 10310 size(4); 10311 ins_encode %{ 10312 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10313 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10314 %} 10315 ins_pipe(pipe_class_default); 10316 %} 10317 10318 // Expand does not work with above instruct. (??) 10319 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10320 // no match-rule 10321 effect(DEF dst, USE src1, USE src2); 10322 format %{ "OR $dst, $src1, $src2" %} 10323 size(4); 10324 ins_encode %{ 10325 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10326 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10327 %} 10328 ins_pipe(pipe_class_default); 10329 %} 10330 10331 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10332 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10333 ins_cost(DEFAULT_COST*3); 10334 10335 expand %{ 10336 // FIXME: we should do this in the ideal world. 10337 iRegIdst tmp1; 10338 iRegIdst tmp2; 10339 orI_reg_reg(tmp1, src1, src2); 10340 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10341 orI_reg_reg(dst, tmp1, tmp2); 10342 %} 10343 %} 10344 10345 // Immediate Or 10346 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10347 match(Set dst (OrI src1 src2)); 10348 format %{ "ORI $dst, $src1, $src2" %} 10349 size(4); 10350 ins_encode %{ 10351 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10352 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10353 %} 10354 ins_pipe(pipe_class_default); 10355 %} 10356 10357 // Register Or Long 10358 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10359 match(Set dst (OrL src1 src2)); 10360 ins_cost(DEFAULT_COST); 10361 10362 size(4); 10363 format %{ "OR $dst, $src1, $src2 \t// long" %} 10364 ins_encode %{ 10365 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10366 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10367 %} 10368 ins_pipe(pipe_class_default); 10369 %} 10370 10371 // OrL + ConvL2I. 10372 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10373 match(Set dst (ConvL2I (OrL src1 src2))); 10374 ins_cost(DEFAULT_COST); 10375 10376 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10377 size(4); 10378 ins_encode %{ 10379 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10380 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10381 %} 10382 ins_pipe(pipe_class_default); 10383 %} 10384 10385 // Immediate Or long 10386 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10387 match(Set dst (OrL src1 con)); 10388 ins_cost(DEFAULT_COST); 10389 10390 format %{ "ORI $dst, $src1, $con \t// long" %} 10391 size(4); 10392 ins_encode %{ 10393 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10394 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10395 %} 10396 ins_pipe(pipe_class_default); 10397 %} 10398 10399 // Xor Instructions 10400 10401 // Register Xor 10402 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10403 match(Set dst (XorI src1 src2)); 10404 format %{ "XOR $dst, $src1, $src2" %} 10405 size(4); 10406 ins_encode %{ 10407 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10408 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10409 %} 10410 ins_pipe(pipe_class_default); 10411 %} 10412 10413 // Expand does not work with above instruct. (??) 10414 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10415 // no match-rule 10416 effect(DEF dst, USE src1, USE src2); 10417 format %{ "XOR $dst, $src1, $src2" %} 10418 size(4); 10419 ins_encode %{ 10420 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10421 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10422 %} 10423 ins_pipe(pipe_class_default); 10424 %} 10425 10426 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10427 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10428 ins_cost(DEFAULT_COST*3); 10429 10430 expand %{ 10431 // FIXME: we should do this in the ideal world. 10432 iRegIdst tmp1; 10433 iRegIdst tmp2; 10434 xorI_reg_reg(tmp1, src1, src2); 10435 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10436 xorI_reg_reg(dst, tmp1, tmp2); 10437 %} 10438 %} 10439 10440 // Immediate Xor 10441 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10442 match(Set dst (XorI src1 src2)); 10443 format %{ "XORI $dst, $src1, $src2" %} 10444 size(4); 10445 ins_encode %{ 10446 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10447 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10448 %} 10449 ins_pipe(pipe_class_default); 10450 %} 10451 10452 // Register Xor Long 10453 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10454 match(Set dst (XorL src1 src2)); 10455 ins_cost(DEFAULT_COST); 10456 10457 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10458 size(4); 10459 ins_encode %{ 10460 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10461 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10462 %} 10463 ins_pipe(pipe_class_default); 10464 %} 10465 10466 // XorL + ConvL2I. 10467 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10468 match(Set dst (ConvL2I (XorL src1 src2))); 10469 ins_cost(DEFAULT_COST); 10470 10471 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10472 size(4); 10473 ins_encode %{ 10474 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10475 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10476 %} 10477 ins_pipe(pipe_class_default); 10478 %} 10479 10480 // Immediate Xor Long 10481 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10482 match(Set dst (XorL src1 src2)); 10483 ins_cost(DEFAULT_COST); 10484 10485 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10486 size(4); 10487 ins_encode %{ 10488 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10489 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10490 %} 10491 ins_pipe(pipe_class_default); 10492 %} 10493 10494 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10495 match(Set dst (XorI src1 src2)); 10496 ins_cost(DEFAULT_COST); 10497 10498 format %{ "NOT $dst, $src1 ($src2)" %} 10499 size(4); 10500 ins_encode %{ 10501 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10502 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10503 %} 10504 ins_pipe(pipe_class_default); 10505 %} 10506 10507 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10508 match(Set dst (XorL src1 src2)); 10509 ins_cost(DEFAULT_COST); 10510 10511 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10512 size(4); 10513 ins_encode %{ 10514 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10515 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10516 %} 10517 ins_pipe(pipe_class_default); 10518 %} 10519 10520 // And-complement 10521 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10522 match(Set dst (AndI (XorI src1 src2) src3)); 10523 ins_cost(DEFAULT_COST); 10524 10525 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10526 size(4); 10527 ins_encode( enc_andc(dst, src3, src1) ); 10528 ins_pipe(pipe_class_default); 10529 %} 10530 10531 // And-complement 10532 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10533 // no match-rule, false predicate 10534 effect(DEF dst, USE src1, USE src2); 10535 predicate(false); 10536 10537 format %{ "ANDC $dst, $src1, $src2" %} 10538 size(4); 10539 ins_encode %{ 10540 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10541 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10542 %} 10543 ins_pipe(pipe_class_default); 10544 %} 10545 10546 //----------Moves between int/long and float/double---------------------------- 10547 // 10548 // The following rules move values from int/long registers/stack-locations 10549 // to float/double registers/stack-locations and vice versa, without doing any 10550 // conversions. These rules are used to implement the bit-conversion methods 10551 // of java.lang.Float etc., e.g. 10552 // int floatToIntBits(float value) 10553 // float intBitsToFloat(int bits) 10554 // 10555 // Notes on the implementation on ppc64: 10556 // For Power7 and earlier, the rules are limited to those which move between a 10557 // register and a stack-location, because we always have to go through memory 10558 // when moving between a float register and an integer register. 10559 // This restriction is removed in Power8 with the introduction of the mtfprd 10560 // and mffprd instructions. 10561 10562 instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10563 match(Set dst (MoveL2D src)); 10564 predicate(VM_Version::has_mtfprd()); 10565 10566 format %{ "MTFPRD $dst, $src" %} 10567 size(4); 10568 ins_encode %{ 10569 __ mtfprd($dst$$FloatRegister, $src$$Register); 10570 %} 10571 ins_pipe(pipe_class_default); 10572 %} 10573 10574 instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10575 // no match-rule, false predicate 10576 effect(DEF dst, USE src); 10577 predicate(false); 10578 10579 format %{ "MTFPRWA $dst, $src" %} 10580 size(4); 10581 ins_encode %{ 10582 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10583 %} 10584 ins_pipe(pipe_class_default); 10585 %} 10586 10587 //---------- Chain stack slots between similar types -------- 10588 10589 // These are needed so that the rules below can match. 10590 10591 // Load integer from stack slot 10592 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10593 match(Set dst src); 10594 ins_cost(MEMORY_REF_COST); 10595 10596 format %{ "LWZ $dst, $src" %} 10597 size(4); 10598 ins_encode( enc_lwz(dst, src) ); 10599 ins_pipe(pipe_class_memory); 10600 %} 10601 10602 // Store integer to stack slot 10603 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10604 match(Set dst src); 10605 ins_cost(MEMORY_REF_COST); 10606 10607 format %{ "STW $src, $dst \t// stk" %} 10608 size(4); 10609 ins_encode( enc_stw(src, dst) ); // rs=rt 10610 ins_pipe(pipe_class_memory); 10611 %} 10612 10613 // Load long from stack slot 10614 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10615 match(Set dst src); 10616 ins_cost(MEMORY_REF_COST); 10617 10618 format %{ "LD $dst, $src \t// long" %} 10619 size(4); 10620 ins_encode( enc_ld(dst, src) ); 10621 ins_pipe(pipe_class_memory); 10622 %} 10623 10624 // Store long to stack slot 10625 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10626 match(Set dst src); 10627 ins_cost(MEMORY_REF_COST); 10628 10629 format %{ "STD $src, $dst \t// long" %} 10630 size(4); 10631 ins_encode( enc_std(src, dst) ); // rs=rt 10632 ins_pipe(pipe_class_memory); 10633 %} 10634 10635 //----------Moves between int and float 10636 10637 // Move float value from float stack-location to integer register. 10638 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10639 match(Set dst (MoveF2I src)); 10640 ins_cost(MEMORY_REF_COST); 10641 10642 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10643 size(4); 10644 ins_encode( enc_lwz(dst, src) ); 10645 ins_pipe(pipe_class_memory); 10646 %} 10647 10648 // Move float value from float register to integer stack-location. 10649 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10650 match(Set dst (MoveF2I src)); 10651 ins_cost(MEMORY_REF_COST); 10652 10653 format %{ "STFS $src, $dst \t// MoveF2I" %} 10654 size(4); 10655 ins_encode( enc_stfs(src, dst) ); 10656 ins_pipe(pipe_class_memory); 10657 %} 10658 10659 // Move integer value from integer stack-location to float register. 10660 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10661 match(Set dst (MoveI2F src)); 10662 ins_cost(MEMORY_REF_COST); 10663 10664 format %{ "LFS $dst, $src \t// MoveI2F" %} 10665 size(4); 10666 ins_encode %{ 10667 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10668 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10669 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10670 %} 10671 ins_pipe(pipe_class_memory); 10672 %} 10673 10674 // Move integer value from integer register to float stack-location. 10675 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10676 match(Set dst (MoveI2F src)); 10677 ins_cost(MEMORY_REF_COST); 10678 10679 format %{ "STW $src, $dst \t// MoveI2F" %} 10680 size(4); 10681 ins_encode( enc_stw(src, dst) ); 10682 ins_pipe(pipe_class_memory); 10683 %} 10684 10685 //----------Moves between long and float 10686 10687 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10688 // no match-rule, false predicate 10689 effect(DEF dst, USE src); 10690 predicate(false); 10691 10692 format %{ "storeD $src, $dst \t// STACK" %} 10693 size(4); 10694 ins_encode( enc_stfd(src, dst) ); 10695 ins_pipe(pipe_class_default); 10696 %} 10697 10698 //----------Moves between long and double 10699 10700 // Move double value from double stack-location to long register. 10701 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10702 match(Set dst (MoveD2L src)); 10703 ins_cost(MEMORY_REF_COST); 10704 size(4); 10705 format %{ "LD $dst, $src \t// MoveD2L" %} 10706 ins_encode( enc_ld(dst, src) ); 10707 ins_pipe(pipe_class_memory); 10708 %} 10709 10710 // Move double value from double register to long stack-location. 10711 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10712 match(Set dst (MoveD2L src)); 10713 effect(DEF dst, USE src); 10714 ins_cost(MEMORY_REF_COST); 10715 10716 format %{ "STFD $src, $dst \t// MoveD2L" %} 10717 size(4); 10718 ins_encode( enc_stfd(src, dst) ); 10719 ins_pipe(pipe_class_memory); 10720 %} 10721 10722 // Move long value from long stack-location to double register. 10723 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10724 match(Set dst (MoveL2D src)); 10725 ins_cost(MEMORY_REF_COST); 10726 10727 format %{ "LFD $dst, $src \t// MoveL2D" %} 10728 size(4); 10729 ins_encode( enc_lfd(dst, src) ); 10730 ins_pipe(pipe_class_memory); 10731 %} 10732 10733 // Move long value from long register to double stack-location. 10734 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10735 match(Set dst (MoveL2D src)); 10736 ins_cost(MEMORY_REF_COST); 10737 10738 format %{ "STD $src, $dst \t// MoveL2D" %} 10739 size(4); 10740 ins_encode( enc_std(src, dst) ); 10741 ins_pipe(pipe_class_memory); 10742 %} 10743 10744 //----------Register Move Instructions----------------------------------------- 10745 10746 // Replicate for Superword 10747 10748 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10749 predicate(false); 10750 effect(DEF dst, USE src); 10751 10752 format %{ "MR $dst, $src \t// replicate " %} 10753 // variable size, 0 or 4. 10754 ins_encode %{ 10755 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10756 __ mr_if_needed($dst$$Register, $src$$Register); 10757 %} 10758 ins_pipe(pipe_class_default); 10759 %} 10760 10761 //----------Cast instructions (Java-level type cast)--------------------------- 10762 10763 // Cast Long to Pointer for unsafe natives. 10764 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10765 match(Set dst (CastX2P src)); 10766 10767 format %{ "MR $dst, $src \t// Long->Ptr" %} 10768 // variable size, 0 or 4. 10769 ins_encode %{ 10770 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10771 __ mr_if_needed($dst$$Register, $src$$Register); 10772 %} 10773 ins_pipe(pipe_class_default); 10774 %} 10775 10776 // Cast Pointer to Long for unsafe natives. 10777 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10778 match(Set dst (CastP2X src)); 10779 10780 format %{ "MR $dst, $src \t// Ptr->Long" %} 10781 // variable size, 0 or 4. 10782 ins_encode %{ 10783 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10784 __ mr_if_needed($dst$$Register, $src$$Register); 10785 %} 10786 ins_pipe(pipe_class_default); 10787 %} 10788 10789 instruct castPP(iRegPdst dst) %{ 10790 match(Set dst (CastPP dst)); 10791 format %{ " -- \t// castPP of $dst" %} 10792 size(0); 10793 ins_encode( /*empty*/ ); 10794 ins_pipe(pipe_class_default); 10795 %} 10796 10797 instruct castII(iRegIdst dst) %{ 10798 match(Set dst (CastII dst)); 10799 format %{ " -- \t// castII of $dst" %} 10800 size(0); 10801 ins_encode( /*empty*/ ); 10802 ins_pipe(pipe_class_default); 10803 %} 10804 10805 instruct checkCastPP(iRegPdst dst) %{ 10806 match(Set dst (CheckCastPP dst)); 10807 format %{ " -- \t// checkcastPP of $dst" %} 10808 size(0); 10809 ins_encode( /*empty*/ ); 10810 ins_pipe(pipe_class_default); 10811 %} 10812 10813 //----------Convert instructions----------------------------------------------- 10814 10815 // Convert to boolean. 10816 10817 // int_to_bool(src) : { 1 if src != 0 10818 // { 0 else 10819 // 10820 // strategy: 10821 // 1) Count leading zeros of 32 bit-value src, 10822 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10823 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10824 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10825 10826 // convI2Bool 10827 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10828 match(Set dst (Conv2B src)); 10829 predicate(UseCountLeadingZerosInstructionsPPC64); 10830 ins_cost(DEFAULT_COST); 10831 10832 expand %{ 10833 immI shiftAmount %{ 0x5 %} 10834 uimmI16 mask %{ 0x1 %} 10835 iRegIdst tmp1; 10836 iRegIdst tmp2; 10837 countLeadingZerosI(tmp1, src); 10838 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10839 xorI_reg_uimm16(dst, tmp2, mask); 10840 %} 10841 %} 10842 10843 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10844 match(Set dst (Conv2B src)); 10845 effect(TEMP crx); 10846 predicate(!UseCountLeadingZerosInstructionsPPC64); 10847 ins_cost(DEFAULT_COST); 10848 10849 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10850 "LI $dst, #0\n\t" 10851 "BEQ $crx, done\n\t" 10852 "LI $dst, #1\n" 10853 "done:" %} 10854 size(16); 10855 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10856 ins_pipe(pipe_class_compare); 10857 %} 10858 10859 // ConvI2B + XorI 10860 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10861 match(Set dst (XorI (Conv2B src) mask)); 10862 predicate(UseCountLeadingZerosInstructionsPPC64); 10863 ins_cost(DEFAULT_COST); 10864 10865 expand %{ 10866 immI shiftAmount %{ 0x5 %} 10867 iRegIdst tmp1; 10868 countLeadingZerosI(tmp1, src); 10869 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10870 %} 10871 %} 10872 10873 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10874 match(Set dst (XorI (Conv2B src) mask)); 10875 effect(TEMP crx); 10876 predicate(!UseCountLeadingZerosInstructionsPPC64); 10877 ins_cost(DEFAULT_COST); 10878 10879 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10880 "LI $dst, #1\n\t" 10881 "BEQ $crx, done\n\t" 10882 "LI $dst, #0\n" 10883 "done:" %} 10884 size(16); 10885 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10886 ins_pipe(pipe_class_compare); 10887 %} 10888 10889 // AndI 0b0..010..0 + ConvI2B 10890 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10891 match(Set dst (Conv2B (AndI src mask))); 10892 predicate(UseRotateAndMaskInstructionsPPC64); 10893 ins_cost(DEFAULT_COST); 10894 10895 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10896 size(4); 10897 ins_encode %{ 10898 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10899 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10900 %} 10901 ins_pipe(pipe_class_default); 10902 %} 10903 10904 // Convert pointer to boolean. 10905 // 10906 // ptr_to_bool(src) : { 1 if src != 0 10907 // { 0 else 10908 // 10909 // strategy: 10910 // 1) Count leading zeros of 64 bit-value src, 10911 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10912 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10913 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10914 10915 // ConvP2B 10916 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10917 match(Set dst (Conv2B src)); 10918 predicate(UseCountLeadingZerosInstructionsPPC64); 10919 ins_cost(DEFAULT_COST); 10920 10921 expand %{ 10922 immI shiftAmount %{ 0x6 %} 10923 uimmI16 mask %{ 0x1 %} 10924 iRegIdst tmp1; 10925 iRegIdst tmp2; 10926 countLeadingZerosP(tmp1, src); 10927 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10928 xorI_reg_uimm16(dst, tmp2, mask); 10929 %} 10930 %} 10931 10932 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10933 match(Set dst (Conv2B src)); 10934 effect(TEMP crx); 10935 predicate(!UseCountLeadingZerosInstructionsPPC64); 10936 ins_cost(DEFAULT_COST); 10937 10938 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10939 "LI $dst, #0\n\t" 10940 "BEQ $crx, done\n\t" 10941 "LI $dst, #1\n" 10942 "done:" %} 10943 size(16); 10944 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10945 ins_pipe(pipe_class_compare); 10946 %} 10947 10948 // ConvP2B + XorI 10949 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10950 match(Set dst (XorI (Conv2B src) mask)); 10951 predicate(UseCountLeadingZerosInstructionsPPC64); 10952 ins_cost(DEFAULT_COST); 10953 10954 expand %{ 10955 immI shiftAmount %{ 0x6 %} 10956 iRegIdst tmp1; 10957 countLeadingZerosP(tmp1, src); 10958 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10959 %} 10960 %} 10961 10962 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10963 match(Set dst (XorI (Conv2B src) mask)); 10964 effect(TEMP crx); 10965 predicate(!UseCountLeadingZerosInstructionsPPC64); 10966 ins_cost(DEFAULT_COST); 10967 10968 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10969 "LI $dst, #1\n\t" 10970 "BEQ $crx, done\n\t" 10971 "LI $dst, #0\n" 10972 "done:" %} 10973 size(16); 10974 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10975 ins_pipe(pipe_class_compare); 10976 %} 10977 10978 // if src1 < src2, return -1 else return 0 10979 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10980 match(Set dst (CmpLTMask src1 src2)); 10981 ins_cost(DEFAULT_COST*4); 10982 10983 expand %{ 10984 iRegLdst src1s; 10985 iRegLdst src2s; 10986 iRegLdst diff; 10987 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10988 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10989 subL_reg_reg(diff, src1s, src2s); 10990 // Need to consider >=33 bit result, therefore we need signmaskL. 10991 signmask64I_regL(dst, diff); 10992 %} 10993 %} 10994 10995 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10996 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10997 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10998 size(4); 10999 ins_encode %{ 11000 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11001 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11002 %} 11003 ins_pipe(pipe_class_default); 11004 %} 11005 11006 //----------Arithmetic Conversion Instructions--------------------------------- 11007 11008 // Convert to Byte -- nop 11009 // Convert to Short -- nop 11010 11011 // Convert to Int 11012 11013 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11014 match(Set dst (RShiftI (LShiftI src amount) amount)); 11015 format %{ "EXTSB $dst, $src \t// byte->int" %} 11016 size(4); 11017 ins_encode %{ 11018 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11019 __ extsb($dst$$Register, $src$$Register); 11020 %} 11021 ins_pipe(pipe_class_default); 11022 %} 11023 11024 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11025 effect(DEF dst, USE src); 11026 11027 size(4); 11028 ins_encode %{ 11029 __ extsh($dst$$Register, $src$$Register); 11030 %} 11031 ins_pipe(pipe_class_default); 11032 %} 11033 11034 // LShiftI 16 + RShiftI 16 converts short to int. 11035 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11036 match(Set dst (RShiftI (LShiftI src amount) amount)); 11037 format %{ "EXTSH $dst, $src \t// short->int" %} 11038 size(4); 11039 ins_encode %{ 11040 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11041 __ extsh($dst$$Register, $src$$Register); 11042 %} 11043 ins_pipe(pipe_class_default); 11044 %} 11045 11046 // ConvL2I + ConvI2L: Sign extend int in long register. 11047 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11048 match(Set dst (ConvI2L (ConvL2I src))); 11049 11050 format %{ "EXTSW $dst, $src \t// long->long" %} 11051 size(4); 11052 ins_encode %{ 11053 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11054 __ extsw($dst$$Register, $src$$Register); 11055 %} 11056 ins_pipe(pipe_class_default); 11057 %} 11058 11059 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11060 match(Set dst (ConvL2I src)); 11061 format %{ "MR $dst, $src \t// long->int" %} 11062 // variable size, 0 or 4 11063 ins_encode %{ 11064 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11065 __ mr_if_needed($dst$$Register, $src$$Register); 11066 %} 11067 ins_pipe(pipe_class_default); 11068 %} 11069 11070 instruct convD2IRaw_regD(regD dst, regD src) %{ 11071 // no match-rule, false predicate 11072 effect(DEF dst, USE src); 11073 predicate(false); 11074 11075 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11076 size(4); 11077 ins_encode %{ 11078 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11079 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11080 %} 11081 ins_pipe(pipe_class_default); 11082 %} 11083 11084 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 11085 // no match-rule, false predicate 11086 effect(DEF dst, USE crx, USE src); 11087 predicate(false); 11088 11089 ins_variable_size_depending_on_alignment(true); 11090 11091 format %{ "cmovI $crx, $dst, $src" %} 11092 // Worst case is branch + move + stop, no stop without scheduler. 11093 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11094 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11095 ins_pipe(pipe_class_default); 11096 %} 11097 11098 instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11099 // no match-rule, false predicate 11100 effect(DEF dst, USE crx, USE src); 11101 predicate(false); 11102 11103 ins_variable_size_depending_on_alignment(true); 11104 11105 format %{ "cmovI $crx, $dst, $src" %} 11106 // Worst case is branch + move + stop, no stop without scheduler. 11107 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11108 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11109 ins_pipe(pipe_class_default); 11110 %} 11111 11112 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11113 // no match-rule, false predicate 11114 effect(DEF dst, USE crx, USE mem); 11115 predicate(false); 11116 11117 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11118 postalloc_expand %{ 11119 // 11120 // replaces 11121 // 11122 // region dst crx mem 11123 // \ | | / 11124 // dst=cmovI_bso_stackSlotL_conLvalue0 11125 // 11126 // with 11127 // 11128 // region dst 11129 // \ / 11130 // dst=loadConI16(0) 11131 // | 11132 // ^ region dst crx mem 11133 // | \ | | / 11134 // dst=cmovI_bso_stackSlotL 11135 // 11136 11137 // Create new nodes. 11138 MachNode *m1 = new loadConI16Node(); 11139 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11140 11141 // inputs for new nodes 11142 m1->add_req(n_region); 11143 m2->add_req(n_region, n_crx, n_mem); 11144 11145 // precedences for new nodes 11146 m2->add_prec(m1); 11147 11148 // operands for new nodes 11149 m1->_opnds[0] = op_dst; 11150 m1->_opnds[1] = new immI16Oper(0); 11151 11152 m2->_opnds[0] = op_dst; 11153 m2->_opnds[1] = op_crx; 11154 m2->_opnds[2] = op_mem; 11155 11156 // registers for new nodes 11157 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11158 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11159 11160 // Insert new nodes. 11161 nodes->push(m1); 11162 nodes->push(m2); 11163 %} 11164 %} 11165 11166 instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11167 // no match-rule, false predicate 11168 effect(DEF dst, USE crx, USE src); 11169 predicate(false); 11170 11171 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11172 postalloc_expand %{ 11173 // 11174 // replaces 11175 // 11176 // region dst crx src 11177 // \ | | / 11178 // dst=cmovI_bso_reg_conLvalue0 11179 // 11180 // with 11181 // 11182 // region dst 11183 // \ / 11184 // dst=loadConI16(0) 11185 // | 11186 // ^ region dst crx src 11187 // | \ | | / 11188 // dst=cmovI_bso_reg 11189 // 11190 11191 // Create new nodes. 11192 MachNode *m1 = new loadConI16Node(); 11193 MachNode *m2 = new cmovI_bso_regNode(); 11194 11195 // inputs for new nodes 11196 m1->add_req(n_region); 11197 m2->add_req(n_region, n_crx, n_src); 11198 11199 // precedences for new nodes 11200 m2->add_prec(m1); 11201 11202 // operands for new nodes 11203 m1->_opnds[0] = op_dst; 11204 m1->_opnds[1] = new immI16Oper(0); 11205 11206 m2->_opnds[0] = op_dst; 11207 m2->_opnds[1] = op_crx; 11208 m2->_opnds[2] = op_src; 11209 11210 // registers for new nodes 11211 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11212 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11213 11214 // Insert new nodes. 11215 nodes->push(m1); 11216 nodes->push(m2); 11217 %} 11218 %} 11219 11220 // Double to Int conversion, NaN is mapped to 0. 11221 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11222 match(Set dst (ConvD2I src)); 11223 predicate(!VM_Version::has_mtfprd()); 11224 ins_cost(DEFAULT_COST); 11225 11226 expand %{ 11227 regD tmpD; 11228 stackSlotL tmpS; 11229 flagsReg crx; 11230 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11231 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11232 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11233 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11234 %} 11235 %} 11236 11237 // Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11238 instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11239 match(Set dst (ConvD2I src)); 11240 predicate(VM_Version::has_mtfprd()); 11241 ins_cost(DEFAULT_COST); 11242 11243 expand %{ 11244 regD tmpD; 11245 flagsReg crx; 11246 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11247 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11248 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11249 %} 11250 %} 11251 11252 instruct convF2IRaw_regF(regF dst, regF src) %{ 11253 // no match-rule, false predicate 11254 effect(DEF dst, USE src); 11255 predicate(false); 11256 11257 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11258 size(4); 11259 ins_encode %{ 11260 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11261 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11262 %} 11263 ins_pipe(pipe_class_default); 11264 %} 11265 11266 // Float to Int conversion, NaN is mapped to 0. 11267 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11268 match(Set dst (ConvF2I src)); 11269 predicate(!VM_Version::has_mtfprd()); 11270 ins_cost(DEFAULT_COST); 11271 11272 expand %{ 11273 regF tmpF; 11274 stackSlotL tmpS; 11275 flagsReg crx; 11276 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11277 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11278 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11279 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11280 %} 11281 %} 11282 11283 // Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11284 instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11285 match(Set dst (ConvF2I src)); 11286 predicate(VM_Version::has_mtfprd()); 11287 ins_cost(DEFAULT_COST); 11288 11289 expand %{ 11290 regF tmpF; 11291 flagsReg crx; 11292 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11293 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11294 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11295 %} 11296 %} 11297 11298 // Convert to Long 11299 11300 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11301 match(Set dst (ConvI2L src)); 11302 format %{ "EXTSW $dst, $src \t// int->long" %} 11303 size(4); 11304 ins_encode %{ 11305 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11306 __ extsw($dst$$Register, $src$$Register); 11307 %} 11308 ins_pipe(pipe_class_default); 11309 %} 11310 11311 // Zero-extend: convert unsigned int to long (convUI2L). 11312 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11313 match(Set dst (AndL (ConvI2L src) mask)); 11314 ins_cost(DEFAULT_COST); 11315 11316 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11317 size(4); 11318 ins_encode %{ 11319 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11320 __ clrldi($dst$$Register, $src$$Register, 32); 11321 %} 11322 ins_pipe(pipe_class_default); 11323 %} 11324 11325 // Zero-extend: convert unsigned int to long in long register. 11326 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11327 match(Set dst (AndL src mask)); 11328 ins_cost(DEFAULT_COST); 11329 11330 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11331 size(4); 11332 ins_encode %{ 11333 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11334 __ clrldi($dst$$Register, $src$$Register, 32); 11335 %} 11336 ins_pipe(pipe_class_default); 11337 %} 11338 11339 instruct convF2LRaw_regF(regF dst, regF src) %{ 11340 // no match-rule, false predicate 11341 effect(DEF dst, USE src); 11342 predicate(false); 11343 11344 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11345 size(4); 11346 ins_encode %{ 11347 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11348 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11349 %} 11350 ins_pipe(pipe_class_default); 11351 %} 11352 11353 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 11354 // no match-rule, false predicate 11355 effect(DEF dst, USE crx, USE src); 11356 predicate(false); 11357 11358 ins_variable_size_depending_on_alignment(true); 11359 11360 format %{ "cmovL $crx, $dst, $src" %} 11361 // Worst case is branch + move + stop, no stop without scheduler. 11362 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11363 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 11364 ins_pipe(pipe_class_default); 11365 %} 11366 11367 instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11368 // no match-rule, false predicate 11369 effect(DEF dst, USE crx, USE src); 11370 predicate(false); 11371 11372 ins_variable_size_depending_on_alignment(true); 11373 11374 format %{ "cmovL $crx, $dst, $src" %} 11375 // Worst case is branch + move + stop, no stop without scheduler. 11376 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11377 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11378 ins_pipe(pipe_class_default); 11379 %} 11380 11381 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11382 // no match-rule, false predicate 11383 effect(DEF dst, USE crx, USE mem); 11384 predicate(false); 11385 11386 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11387 postalloc_expand %{ 11388 // 11389 // replaces 11390 // 11391 // region dst crx mem 11392 // \ | | / 11393 // dst=cmovL_bso_stackSlotL_conLvalue0 11394 // 11395 // with 11396 // 11397 // region dst 11398 // \ / 11399 // dst=loadConL16(0) 11400 // | 11401 // ^ region dst crx mem 11402 // | \ | | / 11403 // dst=cmovL_bso_stackSlotL 11404 // 11405 11406 // Create new nodes. 11407 MachNode *m1 = new loadConL16Node(); 11408 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11409 11410 // inputs for new nodes 11411 m1->add_req(n_region); 11412 m2->add_req(n_region, n_crx, n_mem); 11413 m2->add_prec(m1); 11414 11415 // operands for new nodes 11416 m1->_opnds[0] = op_dst; 11417 m1->_opnds[1] = new immL16Oper(0); 11418 m2->_opnds[0] = op_dst; 11419 m2->_opnds[1] = op_crx; 11420 m2->_opnds[2] = op_mem; 11421 11422 // registers for new nodes 11423 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11424 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11425 11426 // Insert new nodes. 11427 nodes->push(m1); 11428 nodes->push(m2); 11429 %} 11430 %} 11431 11432 instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11433 // no match-rule, false predicate 11434 effect(DEF dst, USE crx, USE src); 11435 predicate(false); 11436 11437 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11438 postalloc_expand %{ 11439 // 11440 // replaces 11441 // 11442 // region dst crx src 11443 // \ | | / 11444 // dst=cmovL_bso_reg_conLvalue0 11445 // 11446 // with 11447 // 11448 // region dst 11449 // \ / 11450 // dst=loadConL16(0) 11451 // | 11452 // ^ region dst crx src 11453 // | \ | | / 11454 // dst=cmovL_bso_reg 11455 // 11456 11457 // Create new nodes. 11458 MachNode *m1 = new loadConL16Node(); 11459 MachNode *m2 = new cmovL_bso_regNode(); 11460 11461 // inputs for new nodes 11462 m1->add_req(n_region); 11463 m2->add_req(n_region, n_crx, n_src); 11464 m2->add_prec(m1); 11465 11466 // operands for new nodes 11467 m1->_opnds[0] = op_dst; 11468 m1->_opnds[1] = new immL16Oper(0); 11469 m2->_opnds[0] = op_dst; 11470 m2->_opnds[1] = op_crx; 11471 m2->_opnds[2] = op_src; 11472 11473 // registers for new nodes 11474 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11475 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11476 11477 // Insert new nodes. 11478 nodes->push(m1); 11479 nodes->push(m2); 11480 %} 11481 %} 11482 11483 // Float to Long conversion, NaN is mapped to 0. 11484 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11485 match(Set dst (ConvF2L src)); 11486 predicate(!VM_Version::has_mtfprd()); 11487 ins_cost(DEFAULT_COST); 11488 11489 expand %{ 11490 regF tmpF; 11491 stackSlotL tmpS; 11492 flagsReg crx; 11493 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11494 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11495 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11496 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11497 %} 11498 %} 11499 11500 // Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11501 instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11502 match(Set dst (ConvF2L src)); 11503 predicate(VM_Version::has_mtfprd()); 11504 ins_cost(DEFAULT_COST); 11505 11506 expand %{ 11507 regF tmpF; 11508 flagsReg crx; 11509 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11510 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11511 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11512 %} 11513 %} 11514 11515 instruct convD2LRaw_regD(regD dst, regD src) %{ 11516 // no match-rule, false predicate 11517 effect(DEF dst, USE src); 11518 predicate(false); 11519 11520 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11521 size(4); 11522 ins_encode %{ 11523 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11524 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11525 %} 11526 ins_pipe(pipe_class_default); 11527 %} 11528 11529 // Double to Long conversion, NaN is mapped to 0. 11530 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11531 match(Set dst (ConvD2L src)); 11532 predicate(!VM_Version::has_mtfprd()); 11533 ins_cost(DEFAULT_COST); 11534 11535 expand %{ 11536 regD tmpD; 11537 stackSlotL tmpS; 11538 flagsReg crx; 11539 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11540 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11541 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11542 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11543 %} 11544 %} 11545 11546 // Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11547 instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11548 match(Set dst (ConvD2L src)); 11549 predicate(VM_Version::has_mtfprd()); 11550 ins_cost(DEFAULT_COST); 11551 11552 expand %{ 11553 regD tmpD; 11554 flagsReg crx; 11555 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11556 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11557 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11558 %} 11559 %} 11560 11561 // Convert to Float 11562 11563 // Placed here as needed in expand. 11564 instruct convL2DRaw_regD(regD dst, regD src) %{ 11565 // no match-rule, false predicate 11566 effect(DEF dst, USE src); 11567 predicate(false); 11568 11569 format %{ "FCFID $dst, $src \t// convL2D" %} 11570 size(4); 11571 ins_encode %{ 11572 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11573 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11574 %} 11575 ins_pipe(pipe_class_default); 11576 %} 11577 11578 // Placed here as needed in expand. 11579 instruct convD2F_reg(regF dst, regD src) %{ 11580 match(Set dst (ConvD2F src)); 11581 format %{ "FRSP $dst, $src \t// convD2F" %} 11582 size(4); 11583 ins_encode %{ 11584 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11585 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11586 %} 11587 ins_pipe(pipe_class_default); 11588 %} 11589 11590 // Integer to Float conversion. 11591 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11592 match(Set dst (ConvI2F src)); 11593 predicate(!VM_Version::has_fcfids()); 11594 ins_cost(DEFAULT_COST); 11595 11596 expand %{ 11597 iRegLdst tmpL; 11598 stackSlotL tmpS; 11599 regD tmpD; 11600 regD tmpD2; 11601 convI2L_reg(tmpL, src); // Sign-extension int to long. 11602 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11603 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11604 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11605 convD2F_reg(dst, tmpD2); // Convert double to float. 11606 %} 11607 %} 11608 11609 instruct convL2FRaw_regF(regF dst, regD src) %{ 11610 // no match-rule, false predicate 11611 effect(DEF dst, USE src); 11612 predicate(false); 11613 11614 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11615 size(4); 11616 ins_encode %{ 11617 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11618 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11619 %} 11620 ins_pipe(pipe_class_default); 11621 %} 11622 11623 // Integer to Float conversion. Special version for Power7. 11624 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11625 match(Set dst (ConvI2F src)); 11626 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11627 ins_cost(DEFAULT_COST); 11628 11629 expand %{ 11630 iRegLdst tmpL; 11631 stackSlotL tmpS; 11632 regD tmpD; 11633 convI2L_reg(tmpL, src); // Sign-extension int to long. 11634 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11635 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11636 convL2FRaw_regF(dst, tmpD); // Convert to float. 11637 %} 11638 %} 11639 11640 // Integer to Float conversion. Special version for Power8. 11641 instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11642 match(Set dst (ConvI2F src)); 11643 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11644 ins_cost(DEFAULT_COST); 11645 11646 expand %{ 11647 regD tmpD; 11648 moveI2D_reg(tmpD, src); 11649 convL2FRaw_regF(dst, tmpD); // Convert to float. 11650 %} 11651 %} 11652 11653 // L2F to avoid runtime call. 11654 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11655 match(Set dst (ConvL2F src)); 11656 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11657 ins_cost(DEFAULT_COST); 11658 11659 expand %{ 11660 stackSlotL tmpS; 11661 regD tmpD; 11662 regL_to_stkL(tmpS, src); // Store long to stack. 11663 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11664 convL2FRaw_regF(dst, tmpD); // Convert to float. 11665 %} 11666 %} 11667 11668 // L2F to avoid runtime call. Special version for Power8. 11669 instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11670 match(Set dst (ConvL2F src)); 11671 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11672 ins_cost(DEFAULT_COST); 11673 11674 expand %{ 11675 regD tmpD; 11676 moveL2D_reg(tmpD, src); 11677 convL2FRaw_regF(dst, tmpD); // Convert to float. 11678 %} 11679 %} 11680 11681 // Moved up as used in expand. 11682 //instruct convD2F_reg(regF dst, regD src) %{%} 11683 11684 // Convert to Double 11685 11686 // Integer to Double conversion. 11687 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11688 match(Set dst (ConvI2D src)); 11689 predicate(!VM_Version::has_mtfprd()); 11690 ins_cost(DEFAULT_COST); 11691 11692 expand %{ 11693 iRegLdst tmpL; 11694 stackSlotL tmpS; 11695 regD tmpD; 11696 convI2L_reg(tmpL, src); // Sign-extension int to long. 11697 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11698 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11699 convL2DRaw_regD(dst, tmpD); // Convert to double. 11700 %} 11701 %} 11702 11703 // Integer to Double conversion. Special version for Power8. 11704 instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11705 match(Set dst (ConvI2D src)); 11706 predicate(VM_Version::has_mtfprd()); 11707 ins_cost(DEFAULT_COST); 11708 11709 expand %{ 11710 regD tmpD; 11711 moveI2D_reg(tmpD, src); 11712 convL2DRaw_regD(dst, tmpD); // Convert to double. 11713 %} 11714 %} 11715 11716 // Long to Double conversion 11717 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11718 match(Set dst (ConvL2D src)); 11719 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11720 11721 expand %{ 11722 regD tmpD; 11723 moveL2D_stack_reg(tmpD, src); 11724 convL2DRaw_regD(dst, tmpD); 11725 %} 11726 %} 11727 11728 // Long to Double conversion. Special version for Power8. 11729 instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11730 match(Set dst (ConvL2D src)); 11731 predicate(VM_Version::has_mtfprd()); 11732 ins_cost(DEFAULT_COST); 11733 11734 expand %{ 11735 regD tmpD; 11736 moveL2D_reg(tmpD, src); 11737 convL2DRaw_regD(dst, tmpD); // Convert to double. 11738 %} 11739 %} 11740 11741 instruct convF2D_reg(regD dst, regF src) %{ 11742 match(Set dst (ConvF2D src)); 11743 format %{ "FMR $dst, $src \t// float->double" %} 11744 // variable size, 0 or 4 11745 ins_encode %{ 11746 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11747 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11748 %} 11749 ins_pipe(pipe_class_default); 11750 %} 11751 11752 //----------Control Flow Instructions------------------------------------------ 11753 // Compare Instructions 11754 11755 // Compare Integers 11756 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11757 match(Set crx (CmpI src1 src2)); 11758 size(4); 11759 format %{ "CMPW $crx, $src1, $src2" %} 11760 ins_encode %{ 11761 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11762 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11763 %} 11764 ins_pipe(pipe_class_compare); 11765 %} 11766 11767 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11768 match(Set crx (CmpI src1 src2)); 11769 format %{ "CMPWI $crx, $src1, $src2" %} 11770 size(4); 11771 ins_encode %{ 11772 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11773 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11774 %} 11775 ins_pipe(pipe_class_compare); 11776 %} 11777 11778 // (src1 & src2) == 0? 11779 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11780 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11781 // r0 is killed 11782 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11783 size(4); 11784 ins_encode %{ 11785 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11786 __ andi_(R0, $src1$$Register, $src2$$constant); 11787 %} 11788 ins_pipe(pipe_class_compare); 11789 %} 11790 11791 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11792 match(Set crx (CmpL src1 src2)); 11793 format %{ "CMPD $crx, $src1, $src2" %} 11794 size(4); 11795 ins_encode %{ 11796 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11797 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11798 %} 11799 ins_pipe(pipe_class_compare); 11800 %} 11801 11802 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11803 match(Set crx (CmpL src1 src2)); 11804 format %{ "CMPDI $crx, $src1, $src2" %} 11805 size(4); 11806 ins_encode %{ 11807 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11808 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11809 %} 11810 ins_pipe(pipe_class_compare); 11811 %} 11812 11813 // Added CmpUL for LoopPredicate. 11814 instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11815 match(Set crx (CmpUL src1 src2)); 11816 format %{ "CMPLD $crx, $src1, $src2" %} 11817 size(4); 11818 ins_encode %{ 11819 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11820 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11821 %} 11822 ins_pipe(pipe_class_compare); 11823 %} 11824 11825 instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11826 match(Set crx (CmpUL src1 src2)); 11827 format %{ "CMPLDI $crx, $src1, $src2" %} 11828 size(4); 11829 ins_encode %{ 11830 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11831 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11832 %} 11833 ins_pipe(pipe_class_compare); 11834 %} 11835 11836 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11837 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11838 // r0 is killed 11839 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11840 size(4); 11841 ins_encode %{ 11842 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11843 __ and_(R0, $src1$$Register, $src2$$Register); 11844 %} 11845 ins_pipe(pipe_class_compare); 11846 %} 11847 11848 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11849 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11850 // r0 is killed 11851 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11852 size(4); 11853 ins_encode %{ 11854 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11855 __ andi_(R0, $src1$$Register, $src2$$constant); 11856 %} 11857 ins_pipe(pipe_class_compare); 11858 %} 11859 11860 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11861 // no match-rule, false predicate 11862 effect(DEF dst, USE crx); 11863 predicate(false); 11864 11865 ins_variable_size_depending_on_alignment(true); 11866 11867 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11868 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11869 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11870 ins_encode %{ 11871 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11872 Label done; 11873 // li(Rdst, 0); // equal -> 0 11874 __ beq($crx$$CondRegister, done); 11875 __ li($dst$$Register, 1); // greater -> +1 11876 __ bgt($crx$$CondRegister, done); 11877 __ li($dst$$Register, -1); // unordered or less -> -1 11878 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11879 __ bind(done); 11880 %} 11881 ins_pipe(pipe_class_compare); 11882 %} 11883 11884 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11885 // no match-rule, false predicate 11886 effect(DEF dst, USE crx); 11887 predicate(false); 11888 11889 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11890 postalloc_expand %{ 11891 // 11892 // replaces 11893 // 11894 // region crx 11895 // \ | 11896 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11897 // 11898 // with 11899 // 11900 // region 11901 // \ 11902 // dst=loadConI16(0) 11903 // | 11904 // ^ region crx 11905 // | \ | 11906 // dst=cmovI_conIvalueMinus1_conIvalue1 11907 // 11908 11909 // Create new nodes. 11910 MachNode *m1 = new loadConI16Node(); 11911 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11912 11913 // inputs for new nodes 11914 m1->add_req(n_region); 11915 m2->add_req(n_region, n_crx); 11916 m2->add_prec(m1); 11917 11918 // operands for new nodes 11919 m1->_opnds[0] = op_dst; 11920 m1->_opnds[1] = new immI16Oper(0); 11921 m2->_opnds[0] = op_dst; 11922 m2->_opnds[1] = op_crx; 11923 11924 // registers for new nodes 11925 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11926 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11927 11928 // Insert new nodes. 11929 nodes->push(m1); 11930 nodes->push(m2); 11931 %} 11932 %} 11933 11934 // Manifest a CmpL3 result in an integer register. Very painful. 11935 // This is the test to avoid. 11936 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11937 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11938 match(Set dst (CmpL3 src1 src2)); 11939 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11940 11941 expand %{ 11942 flagsReg tmp1; 11943 cmpL_reg_reg(tmp1, src1, src2); 11944 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11945 %} 11946 %} 11947 11948 // Implicit range checks. 11949 // A range check in the ideal world has one of the following shapes: 11950 // - (If le (CmpU length index)), (IfTrue throw exception) 11951 // - (If lt (CmpU index length)), (IfFalse throw exception) 11952 // 11953 // Match range check 'If le (CmpU length index)'. 11954 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11955 match(If cmp (CmpU src_length index)); 11956 effect(USE labl); 11957 predicate(TrapBasedRangeChecks && 11958 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11959 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11960 (Matcher::branches_to_uncommon_trap(_leaf))); 11961 11962 ins_is_TrapBasedCheckNode(true); 11963 11964 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11965 size(4); 11966 ins_encode %{ 11967 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11968 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11969 __ trap_range_check_le($src_length$$Register, $index$$constant); 11970 } else { 11971 // Both successors are uncommon traps, probability is 0. 11972 // Node got flipped during fixup flow. 11973 assert($cmp$$cmpcode == 0x9, "must be greater"); 11974 __ trap_range_check_g($src_length$$Register, $index$$constant); 11975 } 11976 %} 11977 ins_pipe(pipe_class_trap); 11978 %} 11979 11980 // Match range check 'If lt (CmpU index length)'. 11981 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11982 match(If cmp (CmpU src_index src_length)); 11983 effect(USE labl); 11984 predicate(TrapBasedRangeChecks && 11985 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11986 _leaf->as_If()->_prob >= PROB_ALWAYS && 11987 (Matcher::branches_to_uncommon_trap(_leaf))); 11988 11989 ins_is_TrapBasedCheckNode(true); 11990 11991 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11992 size(4); 11993 ins_encode %{ 11994 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11995 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11996 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11997 } else { 11998 // Both successors are uncommon traps, probability is 0. 11999 // Node got flipped during fixup flow. 12000 assert($cmp$$cmpcode == 0x8, "must be less"); 12001 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12002 } 12003 %} 12004 ins_pipe(pipe_class_trap); 12005 %} 12006 12007 // Match range check 'If lt (CmpU index length)'. 12008 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12009 match(If cmp (CmpU src_index length)); 12010 effect(USE labl); 12011 predicate(TrapBasedRangeChecks && 12012 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12013 _leaf->as_If()->_prob >= PROB_ALWAYS && 12014 (Matcher::branches_to_uncommon_trap(_leaf))); 12015 12016 ins_is_TrapBasedCheckNode(true); 12017 12018 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12019 size(4); 12020 ins_encode %{ 12021 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12022 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12023 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12024 } else { 12025 // Both successors are uncommon traps, probability is 0. 12026 // Node got flipped during fixup flow. 12027 assert($cmp$$cmpcode == 0x8, "must be less"); 12028 __ trap_range_check_l($src_index$$Register, $length$$constant); 12029 } 12030 %} 12031 ins_pipe(pipe_class_trap); 12032 %} 12033 12034 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12035 match(Set crx (CmpU src1 src2)); 12036 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12037 size(4); 12038 ins_encode %{ 12039 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12040 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12041 %} 12042 ins_pipe(pipe_class_compare); 12043 %} 12044 12045 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12046 match(Set crx (CmpU src1 src2)); 12047 size(4); 12048 format %{ "CMPLWI $crx, $src1, $src2" %} 12049 ins_encode %{ 12050 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12051 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12052 %} 12053 ins_pipe(pipe_class_compare); 12054 %} 12055 12056 // Implicit zero checks (more implicit null checks). 12057 // No constant pool entries required. 12058 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12059 match(If cmp (CmpN value zero)); 12060 effect(USE labl); 12061 predicate(TrapBasedNullChecks && 12062 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12063 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12064 Matcher::branches_to_uncommon_trap(_leaf)); 12065 ins_cost(1); 12066 12067 ins_is_TrapBasedCheckNode(true); 12068 12069 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12070 size(4); 12071 ins_encode %{ 12072 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12073 if ($cmp$$cmpcode == 0xA) { 12074 __ trap_null_check($value$$Register); 12075 } else { 12076 // Both successors are uncommon traps, probability is 0. 12077 // Node got flipped during fixup flow. 12078 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12079 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12080 } 12081 %} 12082 ins_pipe(pipe_class_trap); 12083 %} 12084 12085 // Compare narrow oops. 12086 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12087 match(Set crx (CmpN src1 src2)); 12088 12089 size(4); 12090 ins_cost(2); 12091 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12092 ins_encode %{ 12093 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12094 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12095 %} 12096 ins_pipe(pipe_class_compare); 12097 %} 12098 12099 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12100 match(Set crx (CmpN src1 src2)); 12101 // Make this more expensive than zeroCheckN_iReg_imm0. 12102 ins_cost(2); 12103 12104 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12105 size(4); 12106 ins_encode %{ 12107 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12108 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12109 %} 12110 ins_pipe(pipe_class_compare); 12111 %} 12112 12113 // Implicit zero checks (more implicit null checks). 12114 // No constant pool entries required. 12115 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12116 match(If cmp (CmpP value zero)); 12117 effect(USE labl); 12118 predicate(TrapBasedNullChecks && 12119 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12120 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12121 Matcher::branches_to_uncommon_trap(_leaf)); 12122 ins_cost(1); // Should not be cheaper than zeroCheckN. 12123 12124 ins_is_TrapBasedCheckNode(true); 12125 12126 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12127 size(4); 12128 ins_encode %{ 12129 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12130 if ($cmp$$cmpcode == 0xA) { 12131 __ trap_null_check($value$$Register); 12132 } else { 12133 // Both successors are uncommon traps, probability is 0. 12134 // Node got flipped during fixup flow. 12135 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12136 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12137 } 12138 %} 12139 ins_pipe(pipe_class_trap); 12140 %} 12141 12142 // Compare Pointers 12143 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12144 match(Set crx (CmpP src1 src2)); 12145 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12146 size(4); 12147 ins_encode %{ 12148 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12149 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12150 %} 12151 ins_pipe(pipe_class_compare); 12152 %} 12153 12154 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12155 match(Set crx (CmpP src1 src2)); 12156 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12157 size(4); 12158 ins_encode %{ 12159 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12160 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12161 %} 12162 ins_pipe(pipe_class_compare); 12163 %} 12164 12165 // Used in postalloc expand. 12166 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12167 // This match rule prevents reordering of node before a safepoint. 12168 // This only makes sense if this instructions is used exclusively 12169 // for the expansion of EncodeP! 12170 match(Set crx (CmpP src1 src2)); 12171 predicate(false); 12172 12173 format %{ "CMPDI $crx, $src1, $src2" %} 12174 size(4); 12175 ins_encode %{ 12176 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12177 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12178 %} 12179 ins_pipe(pipe_class_compare); 12180 %} 12181 12182 //----------Float Compares---------------------------------------------------- 12183 12184 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12185 // Needs matchrule, see cmpDUnordered. 12186 match(Set crx (CmpF src1 src2)); 12187 // no match-rule, false predicate 12188 predicate(false); 12189 12190 format %{ "cmpFUrd $crx, $src1, $src2" %} 12191 size(4); 12192 ins_encode %{ 12193 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12194 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12195 %} 12196 ins_pipe(pipe_class_default); 12197 %} 12198 12199 instruct cmov_bns_less(flagsReg crx) %{ 12200 // no match-rule, false predicate 12201 effect(DEF crx); 12202 predicate(false); 12203 12204 ins_variable_size_depending_on_alignment(true); 12205 12206 format %{ "cmov $crx" %} 12207 // Worst case is branch + move + stop, no stop without scheduler. 12208 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12209 ins_encode %{ 12210 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12211 Label done; 12212 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12213 __ li(R0, 0); 12214 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12215 // TODO PPC port __ endgroup_if_needed(_size == 16); 12216 __ bind(done); 12217 %} 12218 ins_pipe(pipe_class_default); 12219 %} 12220 12221 // Compare floating, generate condition code. 12222 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12223 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12224 // 12225 // The following code sequence occurs a lot in mpegaudio: 12226 // 12227 // block BXX: 12228 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12229 // cmpFUrd CCR6, F11, F9 12230 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12231 // cmov CCR6 12232 // 8: instruct branchConSched: 12233 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12234 match(Set crx (CmpF src1 src2)); 12235 ins_cost(DEFAULT_COST+BRANCH_COST); 12236 12237 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12238 postalloc_expand %{ 12239 // 12240 // replaces 12241 // 12242 // region src1 src2 12243 // \ | | 12244 // crx=cmpF_reg_reg 12245 // 12246 // with 12247 // 12248 // region src1 src2 12249 // \ | | 12250 // crx=cmpFUnordered_reg_reg 12251 // | 12252 // ^ region 12253 // | \ 12254 // crx=cmov_bns_less 12255 // 12256 12257 // Create new nodes. 12258 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12259 MachNode *m2 = new cmov_bns_lessNode(); 12260 12261 // inputs for new nodes 12262 m1->add_req(n_region, n_src1, n_src2); 12263 m2->add_req(n_region); 12264 m2->add_prec(m1); 12265 12266 // operands for new nodes 12267 m1->_opnds[0] = op_crx; 12268 m1->_opnds[1] = op_src1; 12269 m1->_opnds[2] = op_src2; 12270 m2->_opnds[0] = op_crx; 12271 12272 // registers for new nodes 12273 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12274 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12275 12276 // Insert new nodes. 12277 nodes->push(m1); 12278 nodes->push(m2); 12279 %} 12280 %} 12281 12282 // Compare float, generate -1,0,1 12283 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12284 match(Set dst (CmpF3 src1 src2)); 12285 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12286 12287 expand %{ 12288 flagsReg tmp1; 12289 cmpFUnordered_reg_reg(tmp1, src1, src2); 12290 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12291 %} 12292 %} 12293 12294 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12295 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12296 // node right before the conditional move using it. 12297 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12298 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12299 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12300 // conditional move was supposed to be spilled. 12301 match(Set crx (CmpD src1 src2)); 12302 // False predicate, shall not be matched. 12303 predicate(false); 12304 12305 format %{ "cmpFUrd $crx, $src1, $src2" %} 12306 size(4); 12307 ins_encode %{ 12308 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12309 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12310 %} 12311 ins_pipe(pipe_class_default); 12312 %} 12313 12314 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12315 match(Set crx (CmpD src1 src2)); 12316 ins_cost(DEFAULT_COST+BRANCH_COST); 12317 12318 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12319 postalloc_expand %{ 12320 // 12321 // replaces 12322 // 12323 // region src1 src2 12324 // \ | | 12325 // crx=cmpD_reg_reg 12326 // 12327 // with 12328 // 12329 // region src1 src2 12330 // \ | | 12331 // crx=cmpDUnordered_reg_reg 12332 // | 12333 // ^ region 12334 // | \ 12335 // crx=cmov_bns_less 12336 // 12337 12338 // create new nodes 12339 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12340 MachNode *m2 = new cmov_bns_lessNode(); 12341 12342 // inputs for new nodes 12343 m1->add_req(n_region, n_src1, n_src2); 12344 m2->add_req(n_region); 12345 m2->add_prec(m1); 12346 12347 // operands for new nodes 12348 m1->_opnds[0] = op_crx; 12349 m1->_opnds[1] = op_src1; 12350 m1->_opnds[2] = op_src2; 12351 m2->_opnds[0] = op_crx; 12352 12353 // registers for new nodes 12354 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12355 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12356 12357 // Insert new nodes. 12358 nodes->push(m1); 12359 nodes->push(m2); 12360 %} 12361 %} 12362 12363 // Compare double, generate -1,0,1 12364 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12365 match(Set dst (CmpD3 src1 src2)); 12366 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12367 12368 expand %{ 12369 flagsReg tmp1; 12370 cmpDUnordered_reg_reg(tmp1, src1, src2); 12371 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12372 %} 12373 %} 12374 12375 //----------Branches--------------------------------------------------------- 12376 // Jump 12377 12378 // Direct Branch. 12379 instruct branch(label labl) %{ 12380 match(Goto); 12381 effect(USE labl); 12382 ins_cost(BRANCH_COST); 12383 12384 format %{ "B $labl" %} 12385 size(4); 12386 ins_encode %{ 12387 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12388 Label d; // dummy 12389 __ bind(d); 12390 Label* p = $labl$$label; 12391 // `p' is `NULL' when this encoding class is used only to 12392 // determine the size of the encoded instruction. 12393 Label& l = (NULL == p)? d : *(p); 12394 __ b(l); 12395 %} 12396 ins_pipe(pipe_class_default); 12397 %} 12398 12399 // Conditional Near Branch 12400 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12401 // Same match rule as `branchConFar'. 12402 match(If cmp crx); 12403 effect(USE lbl); 12404 ins_cost(BRANCH_COST); 12405 12406 // If set to 1 this indicates that the current instruction is a 12407 // short variant of a long branch. This avoids using this 12408 // instruction in first-pass matching. It will then only be used in 12409 // the `Shorten_branches' pass. 12410 ins_short_branch(1); 12411 12412 format %{ "B$cmp $crx, $lbl" %} 12413 size(4); 12414 ins_encode( enc_bc(crx, cmp, lbl) ); 12415 ins_pipe(pipe_class_default); 12416 %} 12417 12418 // This is for cases when the ppc64 `bc' instruction does not 12419 // reach far enough. So we emit a far branch here, which is more 12420 // expensive. 12421 // 12422 // Conditional Far Branch 12423 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12424 // Same match rule as `branchCon'. 12425 match(If cmp crx); 12426 effect(USE crx, USE lbl); 12427 predicate(!false /* TODO: PPC port HB_Schedule*/); 12428 // Higher cost than `branchCon'. 12429 ins_cost(5*BRANCH_COST); 12430 12431 // This is not a short variant of a branch, but the long variant. 12432 ins_short_branch(0); 12433 12434 format %{ "B_FAR$cmp $crx, $lbl" %} 12435 size(8); 12436 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12437 ins_pipe(pipe_class_default); 12438 %} 12439 12440 // Conditional Branch used with Power6 scheduler (can be far or short). 12441 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12442 // Same match rule as `branchCon'. 12443 match(If cmp crx); 12444 effect(USE crx, USE lbl); 12445 predicate(false /* TODO: PPC port HB_Schedule*/); 12446 // Higher cost than `branchCon'. 12447 ins_cost(5*BRANCH_COST); 12448 12449 // Actually size doesn't depend on alignment but on shortening. 12450 ins_variable_size_depending_on_alignment(true); 12451 // long variant. 12452 ins_short_branch(0); 12453 12454 format %{ "B_FAR$cmp $crx, $lbl" %} 12455 size(8); // worst case 12456 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12457 ins_pipe(pipe_class_default); 12458 %} 12459 12460 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12461 match(CountedLoopEnd cmp crx); 12462 effect(USE labl); 12463 ins_cost(BRANCH_COST); 12464 12465 // short variant. 12466 ins_short_branch(1); 12467 12468 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12469 size(4); 12470 ins_encode( enc_bc(crx, cmp, labl) ); 12471 ins_pipe(pipe_class_default); 12472 %} 12473 12474 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12475 match(CountedLoopEnd cmp crx); 12476 effect(USE labl); 12477 predicate(!false /* TODO: PPC port HB_Schedule */); 12478 ins_cost(BRANCH_COST); 12479 12480 // Long variant. 12481 ins_short_branch(0); 12482 12483 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12484 size(8); 12485 ins_encode( enc_bc_far(crx, cmp, labl) ); 12486 ins_pipe(pipe_class_default); 12487 %} 12488 12489 // Conditional Branch used with Power6 scheduler (can be far or short). 12490 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12491 match(CountedLoopEnd cmp crx); 12492 effect(USE labl); 12493 predicate(false /* TODO: PPC port HB_Schedule */); 12494 // Higher cost than `branchCon'. 12495 ins_cost(5*BRANCH_COST); 12496 12497 // Actually size doesn't depend on alignment but on shortening. 12498 ins_variable_size_depending_on_alignment(true); 12499 // Long variant. 12500 ins_short_branch(0); 12501 12502 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12503 size(8); // worst case 12504 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12505 ins_pipe(pipe_class_default); 12506 %} 12507 12508 // ============================================================================ 12509 // Java runtime operations, intrinsics and other complex operations. 12510 12511 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12512 // array for an instance of the superklass. Set a hidden internal cache on a 12513 // hit (cache is checked with exposed code in gen_subtype_check()). Return 12514 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12515 // 12516 // GL TODO: Improve this. 12517 // - result should not be a TEMP 12518 // - Add match rule as on sparc avoiding additional Cmp. 12519 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12520 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12521 match(Set result (PartialSubtypeCheck subklass superklass)); 12522 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12523 ins_cost(DEFAULT_COST*10); 12524 12525 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12526 ins_encode %{ 12527 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12528 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12529 $tmp_klass$$Register, NULL, $result$$Register); 12530 %} 12531 ins_pipe(pipe_class_default); 12532 %} 12533 12534 // inlined locking and unlocking 12535 12536 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12537 match(Set crx (FastLock oop box)); 12538 effect(TEMP tmp1, TEMP tmp2); 12539 predicate(!Compile::current()->use_rtm()); 12540 12541 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12542 ins_encode %{ 12543 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12544 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12545 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12546 UseBiasedLocking && !UseOptoBiasInlining); 12547 // If locking was successfull, crx should indicate 'EQ'. 12548 // The compiler generates a branch to the runtime call to 12549 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12550 %} 12551 ins_pipe(pipe_class_compare); 12552 %} 12553 12554 // Separate version for TM. Use bound register for box to enable USE_KILL. 12555 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12556 match(Set crx (FastLock oop box)); 12557 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12558 predicate(Compile::current()->use_rtm()); 12559 12560 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12561 ins_encode %{ 12562 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12563 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12564 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12565 /*Biased Locking*/ false, 12566 _rtm_counters, _stack_rtm_counters, 12567 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12568 /*TM*/ true, ra_->C->profile_rtm()); 12569 // If locking was successfull, crx should indicate 'EQ'. 12570 // The compiler generates a branch to the runtime call to 12571 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12572 %} 12573 ins_pipe(pipe_class_compare); 12574 %} 12575 12576 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12577 match(Set crx (FastUnlock oop box)); 12578 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12579 predicate(!Compile::current()->use_rtm()); 12580 12581 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12582 ins_encode %{ 12583 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12584 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12585 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12586 UseBiasedLocking && !UseOptoBiasInlining, 12587 false); 12588 // If unlocking was successfull, crx should indicate 'EQ'. 12589 // The compiler generates a branch to the runtime call to 12590 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12591 %} 12592 ins_pipe(pipe_class_compare); 12593 %} 12594 12595 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12596 match(Set crx (FastUnlock oop box)); 12597 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12598 predicate(Compile::current()->use_rtm()); 12599 12600 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12601 ins_encode %{ 12602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12603 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12604 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12605 /*Biased Locking*/ false, /*TM*/ true); 12606 // If unlocking was successfull, crx should indicate 'EQ'. 12607 // The compiler generates a branch to the runtime call to 12608 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12609 %} 12610 ins_pipe(pipe_class_compare); 12611 %} 12612 12613 // Align address. 12614 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12615 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12616 12617 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12618 size(4); 12619 ins_encode %{ 12620 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12621 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12622 %} 12623 ins_pipe(pipe_class_default); 12624 %} 12625 12626 // Array size computation. 12627 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12628 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12629 12630 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12631 size(4); 12632 ins_encode %{ 12633 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12634 __ subf($dst$$Register, $start$$Register, $end$$Register); 12635 %} 12636 ins_pipe(pipe_class_default); 12637 %} 12638 12639 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12640 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12641 match(Set dummy (ClearArray cnt base)); 12642 effect(USE_KILL base, KILL ctr); 12643 ins_cost(2 * MEMORY_REF_COST); 12644 12645 format %{ "ClearArray $cnt, $base" %} 12646 ins_encode %{ 12647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12648 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12649 %} 12650 ins_pipe(pipe_class_default); 12651 %} 12652 12653 // Clear-array with constant large array length. 12654 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12655 match(Set dummy (ClearArray cnt base)); 12656 effect(USE_KILL base, TEMP tmp, KILL ctr); 12657 ins_cost(3 * MEMORY_REF_COST); 12658 12659 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12660 ins_encode %{ 12661 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12662 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12663 %} 12664 ins_pipe(pipe_class_default); 12665 %} 12666 12667 // Clear-array with dynamic array length. 12668 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12669 match(Set dummy (ClearArray cnt base)); 12670 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12671 ins_cost(4 * MEMORY_REF_COST); 12672 12673 format %{ "ClearArray $cnt, $base" %} 12674 ins_encode %{ 12675 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12676 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12677 %} 12678 ins_pipe(pipe_class_default); 12679 %} 12680 12681 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12682 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12683 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12684 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12685 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12686 ins_cost(300); 12687 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12688 ins_encode %{ 12689 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12690 __ string_compare($str1$$Register, $str2$$Register, 12691 $cnt1$$Register, $cnt2$$Register, 12692 $tmp$$Register, 12693 $result$$Register, StrIntrinsicNode::LL); 12694 %} 12695 ins_pipe(pipe_class_default); 12696 %} 12697 12698 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12699 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12700 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12701 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12702 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12703 ins_cost(300); 12704 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12705 ins_encode %{ 12706 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12707 __ string_compare($str1$$Register, $str2$$Register, 12708 $cnt1$$Register, $cnt2$$Register, 12709 $tmp$$Register, 12710 $result$$Register, StrIntrinsicNode::UU); 12711 %} 12712 ins_pipe(pipe_class_default); 12713 %} 12714 12715 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12716 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12717 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12718 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12719 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12720 ins_cost(300); 12721 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12722 ins_encode %{ 12723 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12724 __ string_compare($str1$$Register, $str2$$Register, 12725 $cnt1$$Register, $cnt2$$Register, 12726 $tmp$$Register, 12727 $result$$Register, StrIntrinsicNode::LU); 12728 %} 12729 ins_pipe(pipe_class_default); 12730 %} 12731 12732 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12733 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12734 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12735 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12736 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12737 ins_cost(300); 12738 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12739 ins_encode %{ 12740 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12741 __ string_compare($str2$$Register, $str1$$Register, 12742 $cnt2$$Register, $cnt1$$Register, 12743 $tmp$$Register, 12744 $result$$Register, StrIntrinsicNode::UL); 12745 %} 12746 ins_pipe(pipe_class_default); 12747 %} 12748 12749 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12750 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12751 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12752 match(Set result (StrEquals (Binary str1 str2) cnt)); 12753 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12754 ins_cost(300); 12755 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12756 ins_encode %{ 12757 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12758 __ array_equals(false, $str1$$Register, $str2$$Register, 12759 $cnt$$Register, $tmp$$Register, 12760 $result$$Register, true /* byte */); 12761 %} 12762 ins_pipe(pipe_class_default); 12763 %} 12764 12765 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12766 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12767 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12768 match(Set result (StrEquals (Binary str1 str2) cnt)); 12769 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12770 ins_cost(300); 12771 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12772 ins_encode %{ 12773 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12774 __ array_equals(false, $str1$$Register, $str2$$Register, 12775 $cnt$$Register, $tmp$$Register, 12776 $result$$Register, false /* byte */); 12777 %} 12778 ins_pipe(pipe_class_default); 12779 %} 12780 12781 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12782 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12783 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12784 match(Set result (AryEq ary1 ary2)); 12785 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12786 ins_cost(300); 12787 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12788 ins_encode %{ 12789 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12790 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12791 $tmp1$$Register, $tmp2$$Register, 12792 $result$$Register, true /* byte */); 12793 %} 12794 ins_pipe(pipe_class_default); 12795 %} 12796 12797 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12798 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12799 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12800 match(Set result (AryEq ary1 ary2)); 12801 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12802 ins_cost(300); 12803 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12804 ins_encode %{ 12805 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12806 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12807 $tmp1$$Register, $tmp2$$Register, 12808 $result$$Register, false /* byte */); 12809 %} 12810 ins_pipe(pipe_class_default); 12811 %} 12812 12813 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12814 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12815 iRegIdst tmp1, iRegIdst tmp2, 12816 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12817 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12818 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12819 // Required for EA: check if it is still a type_array. 12820 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12821 ins_cost(150); 12822 12823 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12824 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12825 12826 ins_encode %{ 12827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12828 immPOper *needleOper = (immPOper *)$needleImm; 12829 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12830 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12831 jchar chr; 12832 #ifdef VM_LITTLE_ENDIAN 12833 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12834 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12835 #else 12836 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12837 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12838 #endif 12839 __ string_indexof_char($result$$Register, 12840 $haystack$$Register, $haycnt$$Register, 12841 R0, chr, 12842 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12843 %} 12844 ins_pipe(pipe_class_compare); 12845 %} 12846 12847 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12848 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12849 iRegIdst tmp1, iRegIdst tmp2, 12850 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12851 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12852 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12853 // Required for EA: check if it is still a type_array. 12854 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12855 ins_cost(150); 12856 12857 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12858 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12859 12860 ins_encode %{ 12861 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12862 immPOper *needleOper = (immPOper *)$needleImm; 12863 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12864 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12865 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12866 __ string_indexof_char($result$$Register, 12867 $haystack$$Register, $haycnt$$Register, 12868 R0, chr, 12869 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12870 %} 12871 ins_pipe(pipe_class_compare); 12872 %} 12873 12874 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12875 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12876 iRegIdst tmp1, iRegIdst tmp2, 12877 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12878 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12879 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12880 // Required for EA: check if it is still a type_array. 12881 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12882 ins_cost(150); 12883 12884 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12885 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12886 12887 ins_encode %{ 12888 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12889 immPOper *needleOper = (immPOper *)$needleImm; 12890 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12891 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12892 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12893 __ string_indexof_char($result$$Register, 12894 $haystack$$Register, $haycnt$$Register, 12895 R0, chr, 12896 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12897 %} 12898 ins_pipe(pipe_class_compare); 12899 %} 12900 12901 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12902 rscratch2RegP needle, immI_1 needlecntImm, 12903 iRegIdst tmp1, iRegIdst tmp2, 12904 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12905 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12906 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12907 // Required for EA: check if it is still a type_array. 12908 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12909 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12910 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12911 ins_cost(180); 12912 12913 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12914 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12915 ins_encode %{ 12916 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12917 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12918 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12919 guarantee(needle_values, "sanity"); 12920 jchar chr; 12921 #ifdef VM_LITTLE_ENDIAN 12922 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12923 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12924 #else 12925 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12926 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12927 #endif 12928 __ string_indexof_char($result$$Register, 12929 $haystack$$Register, $haycnt$$Register, 12930 R0, chr, 12931 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12932 %} 12933 ins_pipe(pipe_class_compare); 12934 %} 12935 12936 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12937 rscratch2RegP needle, immI_1 needlecntImm, 12938 iRegIdst tmp1, iRegIdst tmp2, 12939 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12940 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12941 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12942 // Required for EA: check if it is still a type_array. 12943 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12944 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12945 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12946 ins_cost(180); 12947 12948 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12949 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12950 ins_encode %{ 12951 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12952 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12953 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12954 guarantee(needle_values, "sanity"); 12955 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12956 __ string_indexof_char($result$$Register, 12957 $haystack$$Register, $haycnt$$Register, 12958 R0, chr, 12959 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12960 %} 12961 ins_pipe(pipe_class_compare); 12962 %} 12963 12964 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12965 rscratch2RegP needle, immI_1 needlecntImm, 12966 iRegIdst tmp1, iRegIdst tmp2, 12967 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12968 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12969 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12970 // Required for EA: check if it is still a type_array. 12971 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12972 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12973 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12974 ins_cost(180); 12975 12976 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12977 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12978 ins_encode %{ 12979 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12980 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12981 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12982 guarantee(needle_values, "sanity"); 12983 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12984 __ string_indexof_char($result$$Register, 12985 $haystack$$Register, $haycnt$$Register, 12986 R0, chr, 12987 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12988 %} 12989 ins_pipe(pipe_class_compare); 12990 %} 12991 12992 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12993 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12994 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12995 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12996 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12997 ins_cost(180); 12998 12999 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13000 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13001 ins_encode %{ 13002 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13003 __ string_indexof_char($result$$Register, 13004 $haystack$$Register, $haycnt$$Register, 13005 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13006 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13007 %} 13008 ins_pipe(pipe_class_compare); 13009 %} 13010 13011 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13012 iRegPsrc needle, uimmI15 needlecntImm, 13013 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13014 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13015 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13016 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13017 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13018 // Required for EA: check if it is still a type_array. 13019 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13020 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13021 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13022 ins_cost(250); 13023 13024 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13025 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13026 ins_encode %{ 13027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13028 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13029 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13030 13031 __ string_indexof($result$$Register, 13032 $haystack$$Register, $haycnt$$Register, 13033 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13034 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13035 %} 13036 ins_pipe(pipe_class_compare); 13037 %} 13038 13039 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13040 iRegPsrc needle, uimmI15 needlecntImm, 13041 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13042 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13043 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13044 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13045 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13046 // Required for EA: check if it is still a type_array. 13047 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13048 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13049 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13050 ins_cost(250); 13051 13052 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13053 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13054 ins_encode %{ 13055 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13056 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13057 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13058 13059 __ string_indexof($result$$Register, 13060 $haystack$$Register, $haycnt$$Register, 13061 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13062 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13063 %} 13064 ins_pipe(pipe_class_compare); 13065 %} 13066 13067 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13068 iRegPsrc needle, uimmI15 needlecntImm, 13069 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13070 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13071 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13072 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13073 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13074 // Required for EA: check if it is still a type_array. 13075 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13076 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13077 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13078 ins_cost(250); 13079 13080 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13081 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13082 ins_encode %{ 13083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13084 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13085 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13086 13087 __ string_indexof($result$$Register, 13088 $haystack$$Register, $haycnt$$Register, 13089 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13090 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13091 %} 13092 ins_pipe(pipe_class_compare); 13093 %} 13094 13095 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13096 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13097 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13098 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13099 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13100 TEMP_DEF result, 13101 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13102 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13103 ins_cost(300); 13104 13105 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13106 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13107 ins_encode %{ 13108 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13109 __ string_indexof($result$$Register, 13110 $haystack$$Register, $haycnt$$Register, 13111 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13112 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13113 %} 13114 ins_pipe(pipe_class_compare); 13115 %} 13116 13117 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13118 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13119 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13120 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13121 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13122 TEMP_DEF result, 13123 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13124 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13125 ins_cost(300); 13126 13127 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13128 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13129 ins_encode %{ 13130 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13131 __ string_indexof($result$$Register, 13132 $haystack$$Register, $haycnt$$Register, 13133 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13134 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13135 %} 13136 ins_pipe(pipe_class_compare); 13137 %} 13138 13139 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13140 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13141 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13142 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13143 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13144 TEMP_DEF result, 13145 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13146 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13147 ins_cost(300); 13148 13149 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13150 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13151 ins_encode %{ 13152 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13153 __ string_indexof($result$$Register, 13154 $haystack$$Register, $haycnt$$Register, 13155 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13156 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13157 %} 13158 ins_pipe(pipe_class_compare); 13159 %} 13160 13161 // char[] to byte[] compression 13162 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13163 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13164 match(Set result (StrCompressedCopy src (Binary dst len))); 13165 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13166 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13167 ins_cost(300); 13168 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13169 ins_encode %{ 13170 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13171 Label Lskip, Ldone; 13172 __ li($result$$Register, 0); 13173 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13174 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13175 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13176 __ beq(CCR0, Lskip); 13177 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13178 __ bind(Lskip); 13179 __ mr($result$$Register, $len$$Register); 13180 __ bind(Ldone); 13181 %} 13182 ins_pipe(pipe_class_default); 13183 %} 13184 13185 // byte[] to char[] inflation 13186 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13187 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13188 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13189 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13190 ins_cost(300); 13191 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13192 ins_encode %{ 13193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13194 Label Ldone; 13195 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13196 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13197 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13198 __ beq(CCR0, Ldone); 13199 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13200 __ bind(Ldone); 13201 %} 13202 ins_pipe(pipe_class_default); 13203 %} 13204 13205 // StringCoding.java intrinsics 13206 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13207 regCTR ctr, flagsRegCR0 cr0) 13208 %{ 13209 match(Set result (HasNegatives ary1 len)); 13210 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13211 ins_cost(300); 13212 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13213 ins_encode %{ 13214 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13215 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13216 $tmp1$$Register, $tmp2$$Register); 13217 %} 13218 ins_pipe(pipe_class_default); 13219 %} 13220 13221 // encode char[] to byte[] in ISO_8859_1 13222 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13223 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13224 match(Set result (EncodeISOArray src (Binary dst len))); 13225 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13226 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13227 ins_cost(300); 13228 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13229 ins_encode %{ 13230 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13231 Label Lslow, Lfailure1, Lfailure2, Ldone; 13232 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13233 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13234 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13235 __ beq(CCR0, Ldone); 13236 __ bind(Lslow); 13237 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13238 __ li($result$$Register, 0); 13239 __ b(Ldone); 13240 13241 __ bind(Lfailure1); 13242 __ mr($result$$Register, $len$$Register); 13243 __ mfctr($tmp1$$Register); 13244 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13245 __ beq(CCR0, Ldone); 13246 __ b(Lslow); 13247 13248 __ bind(Lfailure2); 13249 __ mfctr($result$$Register); // Remaining characters. 13250 13251 __ bind(Ldone); 13252 __ subf($result$$Register, $result$$Register, $len$$Register); 13253 %} 13254 ins_pipe(pipe_class_default); 13255 %} 13256 13257 13258 //---------- Min/Max Instructions --------------------------------------------- 13259 13260 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13261 match(Set dst (MinI src1 src2)); 13262 ins_cost(DEFAULT_COST*6); 13263 13264 expand %{ 13265 iRegLdst src1s; 13266 iRegLdst src2s; 13267 iRegLdst diff; 13268 iRegLdst sm; 13269 iRegLdst doz; // difference or zero 13270 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13271 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13272 subL_reg_reg(diff, src2s, src1s); 13273 // Need to consider >=33 bit result, therefore we need signmaskL. 13274 signmask64L_regL(sm, diff); 13275 andL_reg_reg(doz, diff, sm); // <=0 13276 addI_regL_regL(dst, doz, src1s); 13277 %} 13278 %} 13279 13280 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13281 match(Set dst (MinI src1 src2)); 13282 effect(KILL cr0); 13283 predicate(VM_Version::has_isel()); 13284 ins_cost(DEFAULT_COST*2); 13285 13286 ins_encode %{ 13287 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13288 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13289 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13290 %} 13291 ins_pipe(pipe_class_default); 13292 %} 13293 13294 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13295 match(Set dst (MaxI src1 src2)); 13296 ins_cost(DEFAULT_COST*6); 13297 13298 expand %{ 13299 iRegLdst src1s; 13300 iRegLdst src2s; 13301 iRegLdst diff; 13302 iRegLdst sm; 13303 iRegLdst doz; // difference or zero 13304 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13305 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13306 subL_reg_reg(diff, src2s, src1s); 13307 // Need to consider >=33 bit result, therefore we need signmaskL. 13308 signmask64L_regL(sm, diff); 13309 andcL_reg_reg(doz, diff, sm); // >=0 13310 addI_regL_regL(dst, doz, src1s); 13311 %} 13312 %} 13313 13314 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13315 match(Set dst (MaxI src1 src2)); 13316 effect(KILL cr0); 13317 predicate(VM_Version::has_isel()); 13318 ins_cost(DEFAULT_COST*2); 13319 13320 ins_encode %{ 13321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13322 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13323 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13324 %} 13325 ins_pipe(pipe_class_default); 13326 %} 13327 13328 //---------- Population Count Instructions ------------------------------------ 13329 13330 // Popcnt for Power7. 13331 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13332 match(Set dst (PopCountI src)); 13333 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13334 ins_cost(DEFAULT_COST); 13335 13336 format %{ "POPCNTW $dst, $src" %} 13337 size(4); 13338 ins_encode %{ 13339 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13340 __ popcntw($dst$$Register, $src$$Register); 13341 %} 13342 ins_pipe(pipe_class_default); 13343 %} 13344 13345 // Popcnt for Power7. 13346 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13347 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13348 match(Set dst (PopCountL src)); 13349 ins_cost(DEFAULT_COST); 13350 13351 format %{ "POPCNTD $dst, $src" %} 13352 size(4); 13353 ins_encode %{ 13354 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13355 __ popcntd($dst$$Register, $src$$Register); 13356 %} 13357 ins_pipe(pipe_class_default); 13358 %} 13359 13360 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13361 match(Set dst (CountLeadingZerosI src)); 13362 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13363 ins_cost(DEFAULT_COST); 13364 13365 format %{ "CNTLZW $dst, $src" %} 13366 size(4); 13367 ins_encode %{ 13368 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13369 __ cntlzw($dst$$Register, $src$$Register); 13370 %} 13371 ins_pipe(pipe_class_default); 13372 %} 13373 13374 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13375 match(Set dst (CountLeadingZerosL src)); 13376 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13377 ins_cost(DEFAULT_COST); 13378 13379 format %{ "CNTLZD $dst, $src" %} 13380 size(4); 13381 ins_encode %{ 13382 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13383 __ cntlzd($dst$$Register, $src$$Register); 13384 %} 13385 ins_pipe(pipe_class_default); 13386 %} 13387 13388 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13389 // no match-rule, false predicate 13390 effect(DEF dst, USE src); 13391 predicate(false); 13392 13393 format %{ "CNTLZD $dst, $src" %} 13394 size(4); 13395 ins_encode %{ 13396 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13397 __ cntlzd($dst$$Register, $src$$Register); 13398 %} 13399 ins_pipe(pipe_class_default); 13400 %} 13401 13402 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13403 match(Set dst (CountTrailingZerosI src)); 13404 predicate(UseCountLeadingZerosInstructionsPPC64); 13405 ins_cost(DEFAULT_COST); 13406 13407 expand %{ 13408 immI16 imm1 %{ (int)-1 %} 13409 immI16 imm2 %{ (int)32 %} 13410 immI_minus1 m1 %{ -1 %} 13411 iRegIdst tmpI1; 13412 iRegIdst tmpI2; 13413 iRegIdst tmpI3; 13414 addI_reg_imm16(tmpI1, src, imm1); 13415 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13416 countLeadingZerosI(tmpI3, tmpI2); 13417 subI_imm16_reg(dst, imm2, tmpI3); 13418 %} 13419 %} 13420 13421 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13422 match(Set dst (CountTrailingZerosL src)); 13423 predicate(UseCountLeadingZerosInstructionsPPC64); 13424 ins_cost(DEFAULT_COST); 13425 13426 expand %{ 13427 immL16 imm1 %{ (long)-1 %} 13428 immI16 imm2 %{ (int)64 %} 13429 iRegLdst tmpL1; 13430 iRegLdst tmpL2; 13431 iRegIdst tmpL3; 13432 addL_reg_imm16(tmpL1, src, imm1); 13433 andcL_reg_reg(tmpL2, tmpL1, src); 13434 countLeadingZerosL(tmpL3, tmpL2); 13435 subI_imm16_reg(dst, imm2, tmpL3); 13436 %} 13437 %} 13438 13439 // Expand nodes for byte_reverse_int. 13440 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13441 effect(DEF dst, USE src, USE pos, USE shift); 13442 predicate(false); 13443 13444 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13445 size(4); 13446 ins_encode %{ 13447 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13448 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13449 %} 13450 ins_pipe(pipe_class_default); 13451 %} 13452 13453 // As insrwi_a, but with USE_DEF. 13454 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13455 effect(USE_DEF dst, USE src, USE pos, USE shift); 13456 predicate(false); 13457 13458 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13459 size(4); 13460 ins_encode %{ 13461 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13462 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13463 %} 13464 ins_pipe(pipe_class_default); 13465 %} 13466 13467 // Just slightly faster than java implementation. 13468 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13469 match(Set dst (ReverseBytesI src)); 13470 ins_cost(7*DEFAULT_COST); 13471 13472 expand %{ 13473 immI16 imm24 %{ (int) 24 %} 13474 immI16 imm16 %{ (int) 16 %} 13475 immI16 imm8 %{ (int) 8 %} 13476 immI16 imm4 %{ (int) 4 %} 13477 immI16 imm0 %{ (int) 0 %} 13478 iRegLdst tmpI1; 13479 iRegLdst tmpI2; 13480 iRegLdst tmpI3; 13481 13482 urShiftI_reg_imm(tmpI1, src, imm24); 13483 insrwi_a(dst, tmpI1, imm24, imm8); 13484 urShiftI_reg_imm(tmpI2, src, imm16); 13485 insrwi(dst, tmpI2, imm8, imm16); 13486 urShiftI_reg_imm(tmpI3, src, imm8); 13487 insrwi(dst, tmpI3, imm8, imm8); 13488 insrwi(dst, src, imm0, imm8); 13489 %} 13490 %} 13491 13492 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13493 match(Set dst (ReverseBytesL src)); 13494 ins_cost(15*DEFAULT_COST); 13495 13496 expand %{ 13497 immI16 imm56 %{ (int) 56 %} 13498 immI16 imm48 %{ (int) 48 %} 13499 immI16 imm40 %{ (int) 40 %} 13500 immI16 imm32 %{ (int) 32 %} 13501 immI16 imm24 %{ (int) 24 %} 13502 immI16 imm16 %{ (int) 16 %} 13503 immI16 imm8 %{ (int) 8 %} 13504 immI16 imm0 %{ (int) 0 %} 13505 iRegLdst tmpL1; 13506 iRegLdst tmpL2; 13507 iRegLdst tmpL3; 13508 iRegLdst tmpL4; 13509 iRegLdst tmpL5; 13510 iRegLdst tmpL6; 13511 13512 // src : |a|b|c|d|e|f|g|h| 13513 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13514 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13515 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13516 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13517 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13518 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13519 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13520 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13521 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13522 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13523 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13524 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13525 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13526 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13527 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13528 %} 13529 %} 13530 13531 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13532 match(Set dst (ReverseBytesUS src)); 13533 ins_cost(2*DEFAULT_COST); 13534 13535 expand %{ 13536 immI16 imm16 %{ (int) 16 %} 13537 immI16 imm8 %{ (int) 8 %} 13538 13539 urShiftI_reg_imm(dst, src, imm8); 13540 insrwi(dst, src, imm16, imm8); 13541 %} 13542 %} 13543 13544 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13545 match(Set dst (ReverseBytesS src)); 13546 ins_cost(3*DEFAULT_COST); 13547 13548 expand %{ 13549 immI16 imm16 %{ (int) 16 %} 13550 immI16 imm8 %{ (int) 8 %} 13551 iRegLdst tmpI1; 13552 13553 urShiftI_reg_imm(tmpI1, src, imm8); 13554 insrwi(tmpI1, src, imm16, imm8); 13555 extsh(dst, tmpI1); 13556 %} 13557 %} 13558 13559 // Load Integer reversed byte order 13560 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13561 match(Set dst (ReverseBytesI (LoadI mem))); 13562 ins_cost(MEMORY_REF_COST); 13563 13564 size(4); 13565 ins_encode %{ 13566 __ lwbrx($dst$$Register, $mem$$Register); 13567 %} 13568 ins_pipe(pipe_class_default); 13569 %} 13570 13571 // Load Long - aligned and reversed 13572 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13573 match(Set dst (ReverseBytesL (LoadL mem))); 13574 predicate(VM_Version::has_ldbrx()); 13575 ins_cost(MEMORY_REF_COST); 13576 13577 size(4); 13578 ins_encode %{ 13579 __ ldbrx($dst$$Register, $mem$$Register); 13580 %} 13581 ins_pipe(pipe_class_default); 13582 %} 13583 13584 // Load unsigned short / char reversed byte order 13585 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13586 match(Set dst (ReverseBytesUS (LoadUS mem))); 13587 ins_cost(MEMORY_REF_COST); 13588 13589 size(4); 13590 ins_encode %{ 13591 __ lhbrx($dst$$Register, $mem$$Register); 13592 %} 13593 ins_pipe(pipe_class_default); 13594 %} 13595 13596 // Load short reversed byte order 13597 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13598 match(Set dst (ReverseBytesS (LoadS mem))); 13599 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13600 13601 size(8); 13602 ins_encode %{ 13603 __ lhbrx($dst$$Register, $mem$$Register); 13604 __ extsh($dst$$Register, $dst$$Register); 13605 %} 13606 ins_pipe(pipe_class_default); 13607 %} 13608 13609 // Store Integer reversed byte order 13610 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13611 match(Set mem (StoreI mem (ReverseBytesI src))); 13612 ins_cost(MEMORY_REF_COST); 13613 13614 size(4); 13615 ins_encode %{ 13616 __ stwbrx($src$$Register, $mem$$Register); 13617 %} 13618 ins_pipe(pipe_class_default); 13619 %} 13620 13621 // Store Long reversed byte order 13622 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13623 match(Set mem (StoreL mem (ReverseBytesL src))); 13624 predicate(VM_Version::has_stdbrx()); 13625 ins_cost(MEMORY_REF_COST); 13626 13627 size(4); 13628 ins_encode %{ 13629 __ stdbrx($src$$Register, $mem$$Register); 13630 %} 13631 ins_pipe(pipe_class_default); 13632 %} 13633 13634 // Store unsigned short / char reversed byte order 13635 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13636 match(Set mem (StoreC mem (ReverseBytesUS src))); 13637 ins_cost(MEMORY_REF_COST); 13638 13639 size(4); 13640 ins_encode %{ 13641 __ sthbrx($src$$Register, $mem$$Register); 13642 %} 13643 ins_pipe(pipe_class_default); 13644 %} 13645 13646 // Store short reversed byte order 13647 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13648 match(Set mem (StoreC mem (ReverseBytesS src))); 13649 ins_cost(MEMORY_REF_COST); 13650 13651 size(4); 13652 ins_encode %{ 13653 __ sthbrx($src$$Register, $mem$$Register); 13654 %} 13655 ins_pipe(pipe_class_default); 13656 %} 13657 13658 instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13659 effect(DEF temp1, USE src); 13660 13661 size(4); 13662 ins_encode %{ 13663 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13664 %} 13665 ins_pipe(pipe_class_default); 13666 %} 13667 13668 instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13669 effect(DEF dst, USE src, USE imm1); 13670 13671 size(4); 13672 ins_encode %{ 13673 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13674 %} 13675 ins_pipe(pipe_class_default); 13676 %} 13677 13678 //---------- Replicate Vector Instructions ------------------------------------ 13679 13680 // Insrdi does replicate if src == dst. 13681 instruct repl32(iRegLdst dst) %{ 13682 predicate(false); 13683 effect(USE_DEF dst); 13684 13685 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13686 size(4); 13687 ins_encode %{ 13688 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13689 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13690 %} 13691 ins_pipe(pipe_class_default); 13692 %} 13693 13694 // Insrdi does replicate if src == dst. 13695 instruct repl48(iRegLdst dst) %{ 13696 predicate(false); 13697 effect(USE_DEF dst); 13698 13699 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13700 size(4); 13701 ins_encode %{ 13702 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13703 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13704 %} 13705 ins_pipe(pipe_class_default); 13706 %} 13707 13708 // Insrdi does replicate if src == dst. 13709 instruct repl56(iRegLdst dst) %{ 13710 predicate(false); 13711 effect(USE_DEF dst); 13712 13713 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13714 size(4); 13715 ins_encode %{ 13716 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13717 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 13718 %} 13719 ins_pipe(pipe_class_default); 13720 %} 13721 13722 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13723 match(Set dst (ReplicateB src)); 13724 predicate(n->as_Vector()->length() == 8); 13725 expand %{ 13726 moveReg(dst, src); 13727 repl56(dst); 13728 repl48(dst); 13729 repl32(dst); 13730 %} 13731 %} 13732 13733 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 13734 match(Set dst (ReplicateB zero)); 13735 predicate(n->as_Vector()->length() == 8); 13736 format %{ "LI $dst, #0 \t// replicate8B" %} 13737 size(4); 13738 ins_encode %{ 13739 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13740 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13741 %} 13742 ins_pipe(pipe_class_default); 13743 %} 13744 13745 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13746 match(Set dst (ReplicateB src)); 13747 predicate(n->as_Vector()->length() == 8); 13748 format %{ "LI $dst, #-1 \t// replicate8B" %} 13749 size(4); 13750 ins_encode %{ 13751 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13752 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13753 %} 13754 ins_pipe(pipe_class_default); 13755 %} 13756 13757 instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 13758 match(Set dst (ReplicateB src)); 13759 predicate(n->as_Vector()->length() == 16); 13760 13761 expand %{ 13762 iRegLdst tmpL; 13763 vecX tmpV; 13764 immI8 imm1 %{ (int) 1 %} 13765 moveReg(tmpL, src); 13766 repl56(tmpL); 13767 repl48(tmpL); 13768 mtvsrwz(tmpV, tmpL); 13769 xxspltw(dst, tmpV, imm1); 13770 %} 13771 %} 13772 13773 instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 13774 match(Set dst (ReplicateB zero)); 13775 predicate(n->as_Vector()->length() == 16); 13776 13777 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 13778 size(4); 13779 ins_encode %{ 13780 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13781 %} 13782 ins_pipe(pipe_class_default); 13783 %} 13784 13785 instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 13786 match(Set dst (ReplicateB src)); 13787 predicate(n->as_Vector()->length() == 16); 13788 13789 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13790 size(4); 13791 ins_encode %{ 13792 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13793 %} 13794 ins_pipe(pipe_class_default); 13795 %} 13796 13797 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13798 match(Set dst (ReplicateS src)); 13799 predicate(n->as_Vector()->length() == 4); 13800 expand %{ 13801 moveReg(dst, src); 13802 repl48(dst); 13803 repl32(dst); 13804 %} 13805 %} 13806 13807 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13808 match(Set dst (ReplicateS zero)); 13809 predicate(n->as_Vector()->length() == 4); 13810 format %{ "LI $dst, #0 \t// replicate4C" %} 13811 size(4); 13812 ins_encode %{ 13813 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13814 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13815 %} 13816 ins_pipe(pipe_class_default); 13817 %} 13818 13819 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13820 match(Set dst (ReplicateS src)); 13821 predicate(n->as_Vector()->length() == 4); 13822 format %{ "LI $dst, -1 \t// replicate4C" %} 13823 size(4); 13824 ins_encode %{ 13825 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13826 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13827 %} 13828 ins_pipe(pipe_class_default); 13829 %} 13830 13831 instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 13832 match(Set dst (ReplicateS src)); 13833 predicate(n->as_Vector()->length() == 8); 13834 13835 expand %{ 13836 iRegLdst tmpL; 13837 vecX tmpV; 13838 immI8 zero %{ (int) 0 %} 13839 moveReg(tmpL, src); 13840 repl48(tmpL); 13841 repl32(tmpL); 13842 mtvsrd(tmpV, tmpL); 13843 xxpermdi(dst, tmpV, tmpV, zero); 13844 %} 13845 %} 13846 13847 instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 13848 match(Set dst (ReplicateS zero)); 13849 predicate(n->as_Vector()->length() == 8); 13850 13851 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 13852 size(4); 13853 ins_encode %{ 13854 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13855 %} 13856 ins_pipe(pipe_class_default); 13857 %} 13858 13859 instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 13860 match(Set dst (ReplicateS src)); 13861 predicate(n->as_Vector()->length() == 8); 13862 13863 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 13864 size(4); 13865 ins_encode %{ 13866 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13867 %} 13868 ins_pipe(pipe_class_default); 13869 %} 13870 13871 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13872 match(Set dst (ReplicateI src)); 13873 predicate(n->as_Vector()->length() == 2); 13874 ins_cost(2 * DEFAULT_COST); 13875 expand %{ 13876 moveReg(dst, src); 13877 repl32(dst); 13878 %} 13879 %} 13880 13881 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13882 match(Set dst (ReplicateI zero)); 13883 predicate(n->as_Vector()->length() == 2); 13884 format %{ "LI $dst, #0 \t// replicate4C" %} 13885 size(4); 13886 ins_encode %{ 13887 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13888 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13889 %} 13890 ins_pipe(pipe_class_default); 13891 %} 13892 13893 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13894 match(Set dst (ReplicateI src)); 13895 predicate(n->as_Vector()->length() == 2); 13896 format %{ "LI $dst, -1 \t// replicate4C" %} 13897 size(4); 13898 ins_encode %{ 13899 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13900 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13901 %} 13902 ins_pipe(pipe_class_default); 13903 %} 13904 13905 instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 13906 match(Set dst (ReplicateI src)); 13907 predicate(n->as_Vector()->length() == 4); 13908 ins_cost(2 * DEFAULT_COST); 13909 13910 expand %{ 13911 iRegLdst tmpL; 13912 vecX tmpV; 13913 immI8 zero %{ (int) 0 %} 13914 moveReg(tmpL, src); 13915 repl32(tmpL); 13916 mtvsrd(tmpV, tmpL); 13917 xxpermdi(dst, tmpV, tmpV, zero); 13918 %} 13919 %} 13920 13921 instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 13922 match(Set dst (ReplicateI zero)); 13923 predicate(n->as_Vector()->length() == 4); 13924 13925 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 13926 size(4); 13927 ins_encode %{ 13928 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13929 %} 13930 ins_pipe(pipe_class_default); 13931 %} 13932 13933 instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 13934 match(Set dst (ReplicateI src)); 13935 predicate(n->as_Vector()->length() == 4); 13936 13937 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 13938 size(4); 13939 ins_encode %{ 13940 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 13941 %} 13942 ins_pipe(pipe_class_default); 13943 %} 13944 13945 // Move float to int register via stack, replicate. 13946 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13947 match(Set dst (ReplicateF src)); 13948 predicate(n->as_Vector()->length() == 2); 13949 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13950 expand %{ 13951 stackSlotL tmpS; 13952 iRegIdst tmpI; 13953 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13954 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13955 moveReg(dst, tmpI); // Move int to long reg. 13956 repl32(dst); // Replicate bitpattern. 13957 %} 13958 %} 13959 13960 // Replicate scalar constant to packed float values in Double register 13961 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13962 match(Set dst (ReplicateF src)); 13963 predicate(n->as_Vector()->length() == 2); 13964 ins_cost(5 * DEFAULT_COST); 13965 13966 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13967 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13968 %} 13969 13970 // Replicate scalar zero constant to packed float values in Double register 13971 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13972 match(Set dst (ReplicateF zero)); 13973 predicate(n->as_Vector()->length() == 2); 13974 13975 format %{ "LI $dst, #0 \t// replicate2F" %} 13976 ins_encode %{ 13977 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13978 __ li($dst$$Register, 0x0); 13979 %} 13980 ins_pipe(pipe_class_default); 13981 %} 13982 13983 13984 //----------Overflow Math Instructions----------------------------------------- 13985 13986 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 13987 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 13988 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 13989 13990 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13991 match(Set cr0 (OverflowAddL op1 op2)); 13992 13993 format %{ "add_ $op1, $op2\t# overflow check long" %} 13994 ins_encode %{ 13995 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13996 __ li(R0, 0); 13997 __ mtxer(R0); // clear XER.SO 13998 __ addo_(R0, $op1$$Register, $op2$$Register); 13999 %} 14000 ins_pipe(pipe_class_default); 14001 %} 14002 14003 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14004 match(Set cr0 (OverflowSubL op1 op2)); 14005 14006 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14007 ins_encode %{ 14008 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14009 __ li(R0, 0); 14010 __ mtxer(R0); // clear XER.SO 14011 __ subfo_(R0, $op2$$Register, $op1$$Register); 14012 %} 14013 ins_pipe(pipe_class_default); 14014 %} 14015 14016 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14017 match(Set cr0 (OverflowSubL zero op2)); 14018 14019 format %{ "nego_ R0, $op2\t# overflow check long" %} 14020 ins_encode %{ 14021 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14022 __ li(R0, 0); 14023 __ mtxer(R0); // clear XER.SO 14024 __ nego_(R0, $op2$$Register); 14025 %} 14026 ins_pipe(pipe_class_default); 14027 %} 14028 14029 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14030 match(Set cr0 (OverflowMulL op1 op2)); 14031 14032 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14033 ins_encode %{ 14034 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14035 __ li(R0, 0); 14036 __ mtxer(R0); // clear XER.SO 14037 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14038 %} 14039 ins_pipe(pipe_class_default); 14040 %} 14041 14042 14043 instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14044 match(Set dst (ReplicateF src)); 14045 predicate(n->as_Vector()->length() == 4); 14046 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14047 expand %{ 14048 stackSlotL tmpS; 14049 iRegIdst tmpI; 14050 iRegLdst tmpL; 14051 vecX tmpV; 14052 immI8 zero %{ (int) 0 %} 14053 14054 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14055 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14056 moveReg(tmpL, tmpI); // Move int to long reg. 14057 repl32(tmpL); // Replicate bitpattern. 14058 mtvsrd(tmpV, tmpL); 14059 xxpermdi(dst, tmpV, tmpV, zero); 14060 %} 14061 %} 14062 14063 instruct repl4F_immF_Ex(vecX dst, immF src) %{ 14064 match(Set dst (ReplicateF src)); 14065 predicate(n->as_Vector()->length() == 4); 14066 ins_cost(10 * DEFAULT_COST); 14067 14068 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase) ); 14069 %} 14070 14071 instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14072 match(Set dst (ReplicateF zero)); 14073 predicate(n->as_Vector()->length() == 4); 14074 14075 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14076 ins_encode %{ 14077 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14078 %} 14079 ins_pipe(pipe_class_default); 14080 %} 14081 14082 instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14083 match(Set dst (ReplicateD src)); 14084 predicate(n->as_Vector()->length() == 2); 14085 expand %{ 14086 stackSlotL tmpS; 14087 iRegLdst tmpL; 14088 iRegLdst tmp; 14089 vecX tmpV; 14090 immI8 zero %{ (int) 0 %} 14091 moveD2L_reg_stack(tmpS, src); 14092 moveD2L_stack_reg(tmpL, tmpS); 14093 mtvsrd(tmpV, tmpL); 14094 xxpermdi(dst, tmpV, tmpV, zero); 14095 %} 14096 %} 14097 14098 instruct repl2D_immI0(vecX dst, immI_0 zero) %{ 14099 match(Set dst (ReplicateD zero)); 14100 predicate(n->as_Vector()->length() == 2); 14101 14102 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14103 size(4); 14104 ins_encode %{ 14105 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14106 %} 14107 ins_pipe(pipe_class_default); 14108 %} 14109 14110 instruct repl2D_immIminus1(vecX dst, immI_minus1 src) %{ 14111 match(Set dst (ReplicateD src)); 14112 predicate(n->as_Vector()->length() == 2); 14113 14114 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14115 size(4); 14116 ins_encode %{ 14117 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14118 %} 14119 ins_pipe(pipe_class_default); 14120 %} 14121 14122 instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14123 predicate(false); 14124 effect(DEF dst, USE src); 14125 14126 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14127 size(4); 14128 ins_encode %{ 14129 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14130 %} 14131 ins_pipe(pipe_class_default); 14132 %} 14133 14134 instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14135 effect(DEF dst, USE src, USE zero); 14136 14137 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14138 size(4); 14139 ins_encode %{ 14140 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14141 %} 14142 ins_pipe(pipe_class_default); 14143 %} 14144 14145 instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14146 effect(DEF dst, USE src1, USE src2, USE zero); 14147 14148 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14149 size(4); 14150 ins_encode %{ 14151 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14152 %} 14153 ins_pipe(pipe_class_default); 14154 %} 14155 14156 instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14157 match(Set dst (ReplicateL src)); 14158 predicate(n->as_Vector()->length() == 2); 14159 expand %{ 14160 vecX tmpV; 14161 immI8 zero %{ (int) 0 %} 14162 mtvsrd(tmpV, src); 14163 xxpermdi(dst, tmpV, tmpV, zero); 14164 %} 14165 %} 14166 14167 instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14168 match(Set dst (ReplicateL zero)); 14169 predicate(n->as_Vector()->length() == 2); 14170 14171 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14172 size(4); 14173 ins_encode %{ 14174 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14175 %} 14176 ins_pipe(pipe_class_default); 14177 %} 14178 14179 instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14180 match(Set dst (ReplicateL src)); 14181 predicate(n->as_Vector()->length() == 2); 14182 14183 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14184 size(4); 14185 ins_encode %{ 14186 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14187 %} 14188 ins_pipe(pipe_class_default); 14189 %} 14190 14191 // ============================================================================ 14192 // Safepoint Instruction 14193 14194 instruct safePoint_poll(iRegPdst poll) %{ 14195 match(SafePoint poll); 14196 14197 // It caused problems to add the effect that r0 is killed, but this 14198 // effect no longer needs to be mentioned, since r0 is not contained 14199 // in a reg_class. 14200 14201 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14202 size(4); 14203 ins_encode( enc_poll(0x0, poll) ); 14204 ins_pipe(pipe_class_default); 14205 %} 14206 14207 // ============================================================================ 14208 // Call Instructions 14209 14210 // Call Java Static Instruction 14211 14212 // Schedulable version of call static node. 14213 instruct CallStaticJavaDirect(method meth) %{ 14214 match(CallStaticJava); 14215 effect(USE meth); 14216 ins_cost(CALL_COST); 14217 14218 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14219 14220 format %{ "CALL,static $meth \t// ==> " %} 14221 size(4); 14222 ins_encode( enc_java_static_call(meth) ); 14223 ins_pipe(pipe_class_call); 14224 %} 14225 14226 // Call Java Dynamic Instruction 14227 14228 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14229 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14230 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14231 // The call destination must still be placed in the constant pool. 14232 instruct CallDynamicJavaDirectSched(method meth) %{ 14233 match(CallDynamicJava); // To get all the data fields we need ... 14234 effect(USE meth); 14235 predicate(false); // ... but never match. 14236 14237 ins_field_load_ic_hi_node(loadConL_hiNode*); 14238 ins_field_load_ic_node(loadConLNode*); 14239 ins_num_consts(1 /* 1 patchable constant: call destination */); 14240 14241 format %{ "BL \t// dynamic $meth ==> " %} 14242 size(4); 14243 ins_encode( enc_java_dynamic_call_sched(meth) ); 14244 ins_pipe(pipe_class_call); 14245 %} 14246 14247 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 14248 // We use postalloc expanded calls if we use inline caches 14249 // and do not update method data. 14250 // 14251 // This instruction has two constants: inline cache (IC) and call destination. 14252 // Loading the inline cache will be postalloc expanded, thus leaving a call with 14253 // one constant. 14254 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14255 match(CallDynamicJava); 14256 effect(USE meth); 14257 predicate(UseInlineCaches); 14258 ins_cost(CALL_COST); 14259 14260 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14261 14262 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14263 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14264 %} 14265 14266 // Compound version of call dynamic java 14267 // We use postalloc expanded calls if we use inline caches 14268 // and do not update method data. 14269 instruct CallDynamicJavaDirect(method meth) %{ 14270 match(CallDynamicJava); 14271 effect(USE meth); 14272 predicate(!UseInlineCaches); 14273 ins_cost(CALL_COST); 14274 14275 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14276 ins_num_consts(4); 14277 14278 format %{ "CALL,dynamic $meth \t// ==> " %} 14279 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14280 ins_pipe(pipe_class_call); 14281 %} 14282 14283 // Call Runtime Instruction 14284 14285 instruct CallRuntimeDirect(method meth) %{ 14286 match(CallRuntime); 14287 effect(USE meth); 14288 ins_cost(CALL_COST); 14289 14290 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14291 // env for callee, C-toc. 14292 ins_num_consts(3); 14293 14294 format %{ "CALL,runtime" %} 14295 ins_encode( enc_java_to_runtime_call(meth) ); 14296 ins_pipe(pipe_class_call); 14297 %} 14298 14299 // Call Leaf 14300 14301 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14302 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14303 effect(DEF dst, USE src); 14304 14305 ins_num_consts(1); 14306 14307 format %{ "MTCTR $src" %} 14308 size(4); 14309 ins_encode( enc_leaf_call_mtctr(src) ); 14310 ins_pipe(pipe_class_default); 14311 %} 14312 14313 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 14314 instruct CallLeafDirect(method meth) %{ 14315 match(CallLeaf); // To get the data all the data fields we need ... 14316 effect(USE meth); 14317 predicate(false); // but never match. 14318 14319 format %{ "BCTRL \t// leaf call $meth ==> " %} 14320 size(4); 14321 ins_encode %{ 14322 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14323 __ bctrl(); 14324 %} 14325 ins_pipe(pipe_class_call); 14326 %} 14327 14328 // postalloc expand of CallLeafDirect. 14329 // Load adress to call from TOC, then bl to it. 14330 instruct CallLeafDirect_Ex(method meth) %{ 14331 match(CallLeaf); 14332 effect(USE meth); 14333 ins_cost(CALL_COST); 14334 14335 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14336 // env for callee, C-toc. 14337 ins_num_consts(3); 14338 14339 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14340 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14341 %} 14342 14343 // Call runtime without safepoint - same as CallLeaf. 14344 // postalloc expand of CallLeafNoFPDirect. 14345 // Load adress to call from TOC, then bl to it. 14346 instruct CallLeafNoFPDirect_Ex(method meth) %{ 14347 match(CallLeafNoFP); 14348 effect(USE meth); 14349 ins_cost(CALL_COST); 14350 14351 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14352 // env for callee, C-toc. 14353 ins_num_consts(3); 14354 14355 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14356 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14357 %} 14358 14359 // Tail Call; Jump from runtime stub to Java code. 14360 // Also known as an 'interprocedural jump'. 14361 // Target of jump will eventually return to caller. 14362 // TailJump below removes the return address. 14363 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14364 match(TailCall jump_target method_oop); 14365 ins_cost(CALL_COST); 14366 14367 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14368 "BCTR \t// tail call" %} 14369 size(8); 14370 ins_encode %{ 14371 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14372 __ mtctr($jump_target$$Register); 14373 __ bctr(); 14374 %} 14375 ins_pipe(pipe_class_call); 14376 %} 14377 14378 // Return Instruction 14379 instruct Ret() %{ 14380 match(Return); 14381 format %{ "BLR \t// branch to link register" %} 14382 size(4); 14383 ins_encode %{ 14384 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14385 // LR is restored in MachEpilogNode. Just do the RET here. 14386 __ blr(); 14387 %} 14388 ins_pipe(pipe_class_default); 14389 %} 14390 14391 // Tail Jump; remove the return address; jump to target. 14392 // TailCall above leaves the return address around. 14393 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14394 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14395 // "restore" before this instruction (in Epilogue), we need to materialize it 14396 // in %i0. 14397 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14398 match(TailJump jump_target ex_oop); 14399 ins_cost(CALL_COST); 14400 14401 format %{ "LD R4_ARG2 = LR\n\t" 14402 "MTCTR $jump_target\n\t" 14403 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14404 size(12); 14405 ins_encode %{ 14406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14407 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14408 __ mtctr($jump_target$$Register); 14409 __ bctr(); 14410 %} 14411 ins_pipe(pipe_class_call); 14412 %} 14413 14414 // Create exception oop: created by stack-crawling runtime code. 14415 // Created exception is now available to this handler, and is setup 14416 // just prior to jumping to this handler. No code emitted. 14417 instruct CreateException(rarg1RegP ex_oop) %{ 14418 match(Set ex_oop (CreateEx)); 14419 ins_cost(0); 14420 14421 format %{ " -- \t// exception oop; no code emitted" %} 14422 size(0); 14423 ins_encode( /*empty*/ ); 14424 ins_pipe(pipe_class_default); 14425 %} 14426 14427 // Rethrow exception: The exception oop will come in the first 14428 // argument position. Then JUMP (not call) to the rethrow stub code. 14429 instruct RethrowException() %{ 14430 match(Rethrow); 14431 ins_cost(CALL_COST); 14432 14433 format %{ "Jmp rethrow_stub" %} 14434 ins_encode %{ 14435 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14436 cbuf.set_insts_mark(); 14437 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14438 %} 14439 ins_pipe(pipe_class_call); 14440 %} 14441 14442 // Die now. 14443 instruct ShouldNotReachHere() %{ 14444 match(Halt); 14445 ins_cost(CALL_COST); 14446 14447 format %{ "ShouldNotReachHere" %} 14448 size(4); 14449 ins_encode %{ 14450 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14451 __ trap_should_not_reach_here(); 14452 %} 14453 ins_pipe(pipe_class_default); 14454 %} 14455 14456 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 14457 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14458 // Get a DEF on threadRegP, no costs, no encoding, use 14459 // 'ins_should_rematerialize(true)' to avoid spilling. 14460 instruct tlsLoadP(threadRegP dst) %{ 14461 match(Set dst (ThreadLocal)); 14462 ins_cost(0); 14463 14464 ins_should_rematerialize(true); 14465 14466 format %{ " -- \t// $dst=Thread::current(), empty" %} 14467 size(0); 14468 ins_encode( /*empty*/ ); 14469 ins_pipe(pipe_class_empty); 14470 %} 14471 14472 //---Some PPC specific nodes--------------------------------------------------- 14473 14474 // Stop a group. 14475 instruct endGroup() %{ 14476 ins_cost(0); 14477 14478 ins_is_nop(true); 14479 14480 format %{ "End Bundle (ori r1, r1, 0)" %} 14481 size(4); 14482 ins_encode %{ 14483 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14484 __ endgroup(); 14485 %} 14486 ins_pipe(pipe_class_default); 14487 %} 14488 14489 // Nop instructions 14490 14491 instruct fxNop() %{ 14492 ins_cost(0); 14493 14494 ins_is_nop(true); 14495 14496 format %{ "fxNop" %} 14497 size(4); 14498 ins_encode %{ 14499 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14500 __ nop(); 14501 %} 14502 ins_pipe(pipe_class_default); 14503 %} 14504 14505 instruct fpNop0() %{ 14506 ins_cost(0); 14507 14508 ins_is_nop(true); 14509 14510 format %{ "fpNop0" %} 14511 size(4); 14512 ins_encode %{ 14513 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14514 __ fpnop0(); 14515 %} 14516 ins_pipe(pipe_class_default); 14517 %} 14518 14519 instruct fpNop1() %{ 14520 ins_cost(0); 14521 14522 ins_is_nop(true); 14523 14524 format %{ "fpNop1" %} 14525 size(4); 14526 ins_encode %{ 14527 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14528 __ fpnop1(); 14529 %} 14530 ins_pipe(pipe_class_default); 14531 %} 14532 14533 instruct brNop0() %{ 14534 ins_cost(0); 14535 size(4); 14536 format %{ "brNop0" %} 14537 ins_encode %{ 14538 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14539 __ brnop0(); 14540 %} 14541 ins_is_nop(true); 14542 ins_pipe(pipe_class_default); 14543 %} 14544 14545 instruct brNop1() %{ 14546 ins_cost(0); 14547 14548 ins_is_nop(true); 14549 14550 format %{ "brNop1" %} 14551 size(4); 14552 ins_encode %{ 14553 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14554 __ brnop1(); 14555 %} 14556 ins_pipe(pipe_class_default); 14557 %} 14558 14559 instruct brNop2() %{ 14560 ins_cost(0); 14561 14562 ins_is_nop(true); 14563 14564 format %{ "brNop2" %} 14565 size(4); 14566 ins_encode %{ 14567 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14568 __ brnop2(); 14569 %} 14570 ins_pipe(pipe_class_default); 14571 %} 14572 14573 //----------PEEPHOLE RULES----------------------------------------------------- 14574 // These must follow all instruction definitions as they use the names 14575 // defined in the instructions definitions. 14576 // 14577 // peepmatch ( root_instr_name [preceeding_instruction]* ); 14578 // 14579 // peepconstraint %{ 14580 // (instruction_number.operand_name relational_op instruction_number.operand_name 14581 // [, ...] ); 14582 // // instruction numbers are zero-based using left to right order in peepmatch 14583 // 14584 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14585 // // provide an instruction_number.operand_name for each operand that appears 14586 // // in the replacement instruction's match rule 14587 // 14588 // ---------VM FLAGS--------------------------------------------------------- 14589 // 14590 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14591 // 14592 // Each peephole rule is given an identifying number starting with zero and 14593 // increasing by one in the order seen by the parser. An individual peephole 14594 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14595 // on the command-line. 14596 // 14597 // ---------CURRENT LIMITATIONS---------------------------------------------- 14598 // 14599 // Only match adjacent instructions in same basic block 14600 // Only equality constraints 14601 // Only constraints between operands, not (0.dest_reg == EAX_enc) 14602 // Only one replacement instruction 14603 // 14604 // ---------EXAMPLE---------------------------------------------------------- 14605 // 14606 // // pertinent parts of existing instructions in architecture description 14607 // instruct movI(eRegI dst, eRegI src) %{ 14608 // match(Set dst (CopyI src)); 14609 // %} 14610 // 14611 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14612 // match(Set dst (AddI dst src)); 14613 // effect(KILL cr); 14614 // %} 14615 // 14616 // // Change (inc mov) to lea 14617 // peephole %{ 14618 // // increment preceeded by register-register move 14619 // peepmatch ( incI_eReg movI ); 14620 // // require that the destination register of the increment 14621 // // match the destination register of the move 14622 // peepconstraint ( 0.dst == 1.dst ); 14623 // // construct a replacement instruction that sets 14624 // // the destination to ( move's source register + one ) 14625 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14626 // %} 14627 // 14628 // Implementation no longer uses movX instructions since 14629 // machine-independent system no longer uses CopyX nodes. 14630 // 14631 // peephole %{ 14632 // peepmatch ( incI_eReg movI ); 14633 // peepconstraint ( 0.dst == 1.dst ); 14634 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14635 // %} 14636 // 14637 // peephole %{ 14638 // peepmatch ( decI_eReg movI ); 14639 // peepconstraint ( 0.dst == 1.dst ); 14640 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14641 // %} 14642 // 14643 // peephole %{ 14644 // peepmatch ( addI_eReg_imm movI ); 14645 // peepconstraint ( 0.dst == 1.dst ); 14646 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14647 // %} 14648 // 14649 // peephole %{ 14650 // peepmatch ( addP_eReg_imm movP ); 14651 // peepconstraint ( 0.dst == 1.dst ); 14652 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14653 // %} 14654 14655 // // Change load of spilled value to only a spill 14656 // instruct storeI(memory mem, eRegI src) %{ 14657 // match(Set mem (StoreI mem src)); 14658 // %} 14659 // 14660 // instruct loadI(eRegI dst, memory mem) %{ 14661 // match(Set dst (LoadI mem)); 14662 // %} 14663 // 14664 peephole %{ 14665 peepmatch ( loadI storeI ); 14666 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14667 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14668 %} 14669 14670 peephole %{ 14671 peepmatch ( loadL storeL ); 14672 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14673 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14674 %} 14675 14676 peephole %{ 14677 peepmatch ( loadP storeP ); 14678 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14679 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14680 %} 14681 14682 //----------SMARTSPILL RULES--------------------------------------------------- 14683 // These must follow all instruction definitions as they use the names 14684 // defined in the instructions definitions.