1// 2// Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. 3// Copyright (c) 2012, 2020 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. 34register %{ 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 351alloc_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 399alloc_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 441alloc_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 454alloc_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 521alloc_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. 554reg_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. 591reg_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 626reg_class rscratch1_bits32_reg(R11); 627reg_class rscratch2_bits32_reg(R12); 628reg_class rarg1_bits32_reg(R3); 629reg_class rarg2_bits32_reg(R4); 630reg_class rarg3_bits32_reg(R5); 631reg_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 638reg_class rscratch1_bits64_reg(R11_H, R11); 639reg_class rscratch2_bits64_reg(R12_H, R12); 640reg_class rarg1_bits64_reg(R3_H, R3); 641reg_class rarg2_bits64_reg(R4_H, R4); 642reg_class rarg3_bits64_reg(R5_H, R5); 643reg_class rarg4_bits64_reg(R6_H, R6); 644// Thread register, 'written' by tlsLoadP, see there. 645reg_class thread_bits64_reg(R16_H, R16); 646 647reg_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. 651reg_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. 689reg_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. 727reg_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. 764reg_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 803reg_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 814reg_class int_flags_ro( 815 CCR0, 816 CCR1, 817 CCR2, 818 CCR3, 819 CCR4, 820 CCR5, 821 CCR6, 822 CCR7 823); 824 825reg_class int_flags_CR0(CCR0); 826reg_class int_flags_CR1(CCR1); 827reg_class int_flags_CR6(CCR6); 828reg_class ctr_reg(SR_CTR); 829 830// ---------------------------- 831// Float Register Classes 832// ---------------------------- 833 834reg_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. 871reg_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 910reg_class vs_reg( 911 // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. 912 VSR32, 913 VSR33, 914 VSR34, 915 VSR35, 916 VSR36, 917 VSR37, 918 VSR38, 919 VSR39, 920 VSR40, 921 VSR41, 922 VSR42, 923 VSR43, 924 VSR44, 925 VSR45, 926 VSR46, 927 VSR47, 928 VSR48, 929 VSR49, 930 VSR50, 931 VSR51 932 // VSR52-VSR63 // nv! 933); 934 935 %} 936 937//----------DEFINITION BLOCK--------------------------------------------------- 938// Define name --> value mappings to inform the ADLC of an integer valued name 939// Current support includes integer values in the range [0, 0x7FFFFFFF] 940// Format: 941// int_def <name> ( <int_value>, <expression>); 942// Generated Code in ad_<arch>.hpp 943// #define <name> (<expression>) 944// // value == <int_value> 945// Generated code in ad_<arch>.cpp adlc_verification() 946// assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 947// 948definitions %{ 949 // The default cost (of an ALU instruction). 950 int_def DEFAULT_COST_LOW ( 30, 30); 951 int_def DEFAULT_COST ( 100, 100); 952 int_def HUGE_COST (1000000, 1000000); 953 954 // Memory refs 955 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 956 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 957 958 // Branches are even more expensive. 959 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 960 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 961%} 962 963 964//----------SOURCE BLOCK------------------------------------------------------- 965// This is a block of C++ code which provides values, functions, and 966// definitions necessary in the rest of the architecture description. 967source_hpp %{ 968 // Header information of the source block. 969 // Method declarations/definitions which are used outside 970 // the ad-scope can conveniently be defined here. 971 // 972 // To keep related declarations/definitions/uses close together, 973 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 974 975 // Returns true if Node n is followed by a MemBar node that 976 // will do an acquire. If so, this node must not do the acquire 977 // operation. 978 bool followed_by_acquire(const Node *n); 979%} 980 981source %{ 982 983#include "oops/klass.inline.hpp" 984 985// Should the Matcher clone shifts on addressing modes, expecting them 986// to be subsumed into complex addressing expressions or compute them 987// into registers? 988bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 989 return clone_base_plus_offset_address(m, mstack, address_visited); 990} 991 992void Compile::reshape_address(AddPNode* addp) { 993} 994 995// Optimize load-acquire. 996// 997// Check if acquire is unnecessary due to following operation that does 998// acquire anyways. 999// Walk the pattern: 1000// 1001// n: Load.acq 1002// | 1003// MemBarAcquire 1004// | | 1005// Proj(ctrl) Proj(mem) 1006// | | 1007// MemBarRelease/Volatile 1008// 1009bool followed_by_acquire(const Node *load) { 1010 assert(load->is_Load(), "So far implemented only for loads."); 1011 1012 // Find MemBarAcquire. 1013 const Node *mba = NULL; 1014 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 1015 const Node *out = load->fast_out(i); 1016 if (out->Opcode() == Op_MemBarAcquire) { 1017 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 1018 mba = out; 1019 break; 1020 } 1021 } 1022 if (!mba) return false; 1023 1024 // Find following MemBar node. 1025 // 1026 // The following node must be reachable by control AND memory 1027 // edge to assure no other operations are in between the two nodes. 1028 // 1029 // So first get the Proj node, mem_proj, to use it to iterate forward. 1030 Node *mem_proj = NULL; 1031 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 1032 mem_proj = mba->fast_out(i); // Runs out of bounds and asserts if Proj not found. 1033 assert(mem_proj->is_Proj(), "only projections here"); 1034 ProjNode *proj = mem_proj->as_Proj(); 1035 if (proj->_con == TypeFunc::Memory && 1036 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 1037 break; 1038 } 1039 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 1040 1041 // Search MemBar behind Proj. If there are other memory operations 1042 // behind the Proj we lost. 1043 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 1044 Node *x = mem_proj->fast_out(j); 1045 // Proj might have an edge to a store or load node which precedes the membar. 1046 if (x->is_Mem()) return false; 1047 1048 // On PPC64 release and volatile are implemented by an instruction 1049 // that also has acquire semantics. I.e. there is no need for an 1050 // acquire before these. 1051 int xop = x->Opcode(); 1052 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 1053 // Make sure we're not missing Call/Phi/MergeMem by checking 1054 // control edges. The control edge must directly lead back 1055 // to the MemBarAcquire 1056 Node *ctrl_proj = x->in(0); 1057 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 1058 return true; 1059 } 1060 } 1061 } 1062 1063 return false; 1064} 1065 1066#define __ _masm. 1067 1068// Tertiary op of a LoadP or StoreP encoding. 1069#define REGP_OP true 1070 1071// **************************************************************************** 1072 1073// REQUIRED FUNCTIONALITY 1074 1075// !!!!! Special hack to get all type of calls to specify the byte offset 1076// from the start of the call to the point where the return address 1077// will point. 1078 1079// PPC port: Removed use of lazy constant construct. 1080 1081int MachCallStaticJavaNode::ret_addr_offset() { 1082 // It's only a single branch-and-link instruction. 1083 return 4; 1084} 1085 1086int MachCallDynamicJavaNode::ret_addr_offset() { 1087 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 1088 // postalloc expanded calls if we use inline caches and do not update method data. 1089 if (UseInlineCaches) return 4; 1090 1091 int vtable_index = this->_vtable_index; 1092 if (vtable_index < 0) { 1093 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 1094 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 1095 return 12; 1096 } else { 1097 return 24 + MacroAssembler::instr_size_for_decode_klass_not_null(); 1098 } 1099} 1100 1101int MachCallRuntimeNode::ret_addr_offset() { 1102#if defined(ABI_ELFv2) 1103 return 28; 1104#else 1105 return 40; 1106#endif 1107} 1108 1109//============================================================================= 1110 1111// condition code conversions 1112 1113static int cc_to_boint(int cc) { 1114 return Assembler::bcondCRbiIs0 | (cc & 8); 1115} 1116 1117static int cc_to_inverse_boint(int cc) { 1118 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 1119} 1120 1121static int cc_to_biint(int cc, int flags_reg) { 1122 return (flags_reg << 2) | (cc & 3); 1123} 1124 1125//============================================================================= 1126 1127// Compute padding required for nodes which need alignment. The padding 1128// is the number of bytes (not instructions) which will be inserted before 1129// the instruction. The padding must match the size of a NOP instruction. 1130 1131// Currently not used on this platform. 1132 1133//============================================================================= 1134 1135// Indicate if the safepoint node needs the polling page as an input. 1136bool SafePointNode::needs_polling_address_input() { 1137 // The address is loaded from thread by a seperate node. 1138 return true; 1139} 1140 1141//============================================================================= 1142 1143// Emit an interrupt that is caught by the debugger (for debugging compiler). 1144void emit_break(CodeBuffer &cbuf) { 1145 MacroAssembler _masm(&cbuf); 1146 __ illtrap(); 1147} 1148 1149#ifndef PRODUCT 1150void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1151 st->print("BREAKPOINT"); 1152} 1153#endif 1154 1155void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1156 emit_break(cbuf); 1157} 1158 1159uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1160 return MachNode::size(ra_); 1161} 1162 1163//============================================================================= 1164 1165void emit_nop(CodeBuffer &cbuf) { 1166 MacroAssembler _masm(&cbuf); 1167 __ nop(); 1168} 1169 1170static inline void emit_long(CodeBuffer &cbuf, int value) { 1171 *((int*)(cbuf.insts_end())) = value; 1172 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1173} 1174 1175//============================================================================= 1176 1177%} // interrupt source 1178 1179source_hpp %{ // Header information of the source block. 1180 1181//-------------------------------------------------------------- 1182//---< Used for optimization in Compile::Shorten_branches >--- 1183//-------------------------------------------------------------- 1184 1185class CallStubImpl { 1186 1187 public: 1188 1189 // Emit call stub, compiled java to interpreter. 1190 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1191 1192 // Size of call trampoline stub. 1193 // This doesn't need to be accurate to the byte, but it 1194 // must be larger than or equal to the real size of the stub. 1195 static uint size_call_trampoline() { 1196 return MacroAssembler::trampoline_stub_size; 1197 } 1198 1199 // number of relocations needed by a call trampoline stub 1200 static uint reloc_call_trampoline() { 1201 return 5; 1202 } 1203 1204}; 1205 1206%} // end source_hpp 1207 1208source %{ 1209 1210// Emit a trampoline stub for a call to a target which is too far away. 1211// 1212// code sequences: 1213// 1214// call-site: 1215// branch-and-link to <destination> or <trampoline stub> 1216// 1217// Related trampoline stub for this call-site in the stub section: 1218// load the call target from the constant pool 1219// branch via CTR (LR/link still points to the call-site above) 1220 1221void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1222 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1223 if (stub == NULL) { 1224 ciEnv::current()->record_out_of_memory_failure(); 1225 } 1226} 1227 1228//============================================================================= 1229 1230// Emit an inline branch-and-link call and a related trampoline stub. 1231// 1232// code sequences: 1233// 1234// call-site: 1235// branch-and-link to <destination> or <trampoline stub> 1236// 1237// Related trampoline stub for this call-site in the stub section: 1238// load the call target from the constant pool 1239// branch via CTR (LR/link still points to the call-site above) 1240// 1241 1242typedef struct { 1243 int insts_call_instruction_offset; 1244 int ret_addr_offset; 1245} EmitCallOffsets; 1246 1247// Emit a branch-and-link instruction that branches to a trampoline. 1248// - Remember the offset of the branch-and-link instruction. 1249// - Add a relocation at the branch-and-link instruction. 1250// - Emit a branch-and-link. 1251// - Remember the return pc offset. 1252EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1253 EmitCallOffsets offsets = { -1, -1 }; 1254 const int start_offset = __ offset(); 1255 offsets.insts_call_instruction_offset = __ offset(); 1256 1257 // No entry point given, use the current pc. 1258 if (entry_point == NULL) entry_point = __ pc(); 1259 1260 // Put the entry point as a constant into the constant pool. 1261 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1262 if (entry_point_toc_addr == NULL) { 1263 ciEnv::current()->record_out_of_memory_failure(); 1264 return offsets; 1265 } 1266 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1267 1268 // Emit the trampoline stub which will be related to the branch-and-link below. 1269 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1270 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1271 __ relocate(rtype); 1272 1273 // Note: At this point we do not have the address of the trampoline 1274 // stub, and the entry point might be too far away for bl, so __ pc() 1275 // serves as dummy and the bl will be patched later. 1276 __ bl((address) __ pc()); 1277 1278 offsets.ret_addr_offset = __ offset() - start_offset; 1279 1280 return offsets; 1281} 1282 1283//============================================================================= 1284 1285// Factory for creating loadConL* nodes for large/small constant pool. 1286 1287static inline jlong replicate_immF(float con) { 1288 // Replicate float con 2 times and pack into vector. 1289 int val = *((int*)&con); 1290 jlong lval = val; 1291 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1292 return lval; 1293} 1294 1295//============================================================================= 1296 1297const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1298int Compile::ConstantTable::calculate_table_base_offset() const { 1299 return 0; // absolute addressing, no offset 1300} 1301 1302bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1303void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1304 iRegPdstOper *op_dst = new iRegPdstOper(); 1305 MachNode *m1 = new loadToc_hiNode(); 1306 MachNode *m2 = new loadToc_loNode(); 1307 1308 m1->add_req(NULL); 1309 m2->add_req(NULL, m1); 1310 m1->_opnds[0] = op_dst; 1311 m2->_opnds[0] = op_dst; 1312 m2->_opnds[1] = op_dst; 1313 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1314 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1315 nodes->push(m1); 1316 nodes->push(m2); 1317} 1318 1319void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1320 // Is postalloc expanded. 1321 ShouldNotReachHere(); 1322} 1323 1324uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1325 return 0; 1326} 1327 1328#ifndef PRODUCT 1329void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1330 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1331} 1332#endif 1333 1334//============================================================================= 1335 1336#ifndef PRODUCT 1337void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1338 Compile* C = ra_->C; 1339 const long framesize = C->frame_slots() << LogBytesPerInt; 1340 1341 st->print("PROLOG\n\t"); 1342 if (C->need_stack_bang(framesize)) { 1343 st->print("stack_overflow_check\n\t"); 1344 } 1345 1346 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1347 st->print("save return pc\n\t"); 1348 st->print("push frame %ld\n\t", -framesize); 1349 } 1350} 1351#endif 1352 1353// Macro used instead of the common __ to emulate the pipes of PPC. 1354// Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1355// micro scheduler to cope with "hand written" assembler like in the prolog. Though 1356// still no scheduling of this code is possible, the micro scheduler is aware of the 1357// code and can update its internal data. The following mechanism is used to achieve this: 1358// The micro scheduler calls size() of each compound node during scheduling. size() does a 1359// dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1360#if 0 // TODO: PPC port 1361#define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1362 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1363 _masm. 1364#define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1365 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1366#define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1367 C->hb_scheduling()->_pdScheduling->advance_offset 1368#else 1369#define ___(op) if (UsePower6SchedulerPPC64) \ 1370 Unimplemented(); \ 1371 _masm. 1372#define ___stop if (UsePower6SchedulerPPC64) \ 1373 Unimplemented() 1374#define ___advance if (UsePower6SchedulerPPC64) \ 1375 Unimplemented() 1376#endif 1377 1378void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1379 Compile* C = ra_->C; 1380 MacroAssembler _masm(&cbuf); 1381 1382 const long framesize = C->frame_size_in_bytes(); 1383 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1384 1385 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1386 1387 const Register return_pc = R20; // Must match return_addr() in frame section. 1388 const Register callers_sp = R21; 1389 const Register push_frame_temp = R22; 1390 const Register toc_temp = R23; 1391 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1392 1393 if (method_is_frameless) { 1394 // Add nop at beginning of all frameless methods to prevent any 1395 // oop instructions from getting overwritten by make_not_entrant 1396 // (patching attempt would fail). 1397 ___(nop) nop(); 1398 } else { 1399 // Get return pc. 1400 ___(mflr) mflr(return_pc); 1401 } 1402 1403 // Calls to C2R adapters often do not accept exceptional returns. 1404 // We require that their callers must bang for them. But be 1405 // careful, because some VM calls (such as call site linkage) can 1406 // use several kilobytes of stack. But the stack safety zone should 1407 // account for that. See bugs 4446381, 4468289, 4497237. 1408 1409 int bangsize = C->bang_size_in_bytes(); 1410 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1411 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1412 // Unfortunately we cannot use the function provided in 1413 // assembler.cpp as we have to emulate the pipes. So I had to 1414 // insert the code of generate_stack_overflow_check(), see 1415 // assembler.cpp for some illuminative comments. 1416 const int page_size = os::vm_page_size(); 1417 int bang_end = JavaThread::stack_shadow_zone_size(); 1418 1419 // This is how far the previous frame's stack banging extended. 1420 const int bang_end_safe = bang_end; 1421 1422 if (bangsize > page_size) { 1423 bang_end += bangsize; 1424 } 1425 1426 int bang_offset = bang_end_safe; 1427 1428 while (bang_offset <= bang_end) { 1429 // Need at least one stack bang at end of shadow zone. 1430 1431 // Again I had to copy code, this time from assembler_ppc.cpp, 1432 // bang_stack_with_offset - see there for comments. 1433 1434 // Stack grows down, caller passes positive offset. 1435 assert(bang_offset > 0, "must bang with positive offset"); 1436 1437 long stdoffset = -bang_offset; 1438 1439 if (Assembler::is_simm(stdoffset, 16)) { 1440 // Signed 16 bit offset, a simple std is ok. 1441 if (UseLoadInstructionsForStackBangingPPC64) { 1442 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1443 } else { 1444 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1445 } 1446 } else if (Assembler::is_simm(stdoffset, 31)) { 1447 // Use largeoffset calculations for addis & ld/std. 1448 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1449 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1450 1451 Register tmp = R11; 1452 ___(addis) addis(tmp, R1_SP, hi); 1453 if (UseLoadInstructionsForStackBangingPPC64) { 1454 ___(ld) ld(R0, lo, tmp); 1455 } else { 1456 ___(std) std(R0, lo, tmp); 1457 } 1458 } else { 1459 ShouldNotReachHere(); 1460 } 1461 1462 bang_offset += page_size; 1463 } 1464 // R11 trashed 1465 } // C->need_stack_bang(framesize) && UseStackBanging 1466 1467 unsigned int bytes = (unsigned int)framesize; 1468 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1469 ciMethod *currMethod = C->method(); 1470 1471 // Optimized version for most common case. 1472 if (UsePower6SchedulerPPC64 && 1473 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1474 !(false /* ConstantsALot TODO: PPC port*/)) { 1475 ___(or) mr(callers_sp, R1_SP); 1476 ___(std) std(return_pc, _abi(lr), R1_SP); 1477 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1478 return; 1479 } 1480 1481 if (!method_is_frameless) { 1482 // Get callers sp. 1483 ___(or) mr(callers_sp, R1_SP); 1484 1485 // Push method's frame, modifies SP. 1486 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1487 // The ABI is already accounted for in 'framesize' via the 1488 // 'out_preserve' area. 1489 Register tmp = push_frame_temp; 1490 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1491 if (Assembler::is_simm(-offset, 16)) { 1492 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1493 } else { 1494 long x = -offset; 1495 // Had to insert load_const(tmp, -offset). 1496 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1497 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1498 ___(rldicr) sldi(tmp, tmp, 32); 1499 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1500 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1501 1502 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1503 } 1504 } 1505#if 0 // TODO: PPC port 1506 // For testing large constant pools, emit a lot of constants to constant pool. 1507 // "Randomize" const_size. 1508 if (ConstantsALot) { 1509 const int num_consts = const_size(); 1510 for (int i = 0; i < num_consts; i++) { 1511 __ long_constant(0xB0B5B00BBABE); 1512 } 1513 } 1514#endif 1515 if (!method_is_frameless) { 1516 // Save return pc. 1517 ___(std) std(return_pc, _abi(lr), callers_sp); 1518 } 1519 1520 C->set_frame_complete(cbuf.insts_size()); 1521} 1522#undef ___ 1523#undef ___stop 1524#undef ___advance 1525 1526uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1527 // Variable size. determine dynamically. 1528 return MachNode::size(ra_); 1529} 1530 1531int MachPrologNode::reloc() const { 1532 // Return number of relocatable values contained in this instruction. 1533 return 1; // 1 reloc entry for load_const(toc). 1534} 1535 1536//============================================================================= 1537 1538#ifndef PRODUCT 1539void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1540 Compile* C = ra_->C; 1541 1542 st->print("EPILOG\n\t"); 1543 st->print("restore return pc\n\t"); 1544 st->print("pop frame\n\t"); 1545 1546 if (do_polling() && C->is_method_compilation()) { 1547 st->print("touch polling page\n\t"); 1548 } 1549} 1550#endif 1551 1552void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1553 Compile* C = ra_->C; 1554 MacroAssembler _masm(&cbuf); 1555 1556 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1557 assert(framesize >= 0, "negative frame-size?"); 1558 1559 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1560 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1561 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1562 const Register polling_page = R12; 1563 1564 if (!method_is_frameless) { 1565 // Restore return pc relative to callers' sp. 1566 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1567 } 1568 1569 if (method_needs_polling) { 1570 if (SafepointMechanism::uses_thread_local_poll()) { 1571 __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); 1572 } else { 1573 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); 1574 } 1575 } 1576 1577 if (!method_is_frameless) { 1578 // Move return pc to LR. 1579 __ mtlr(return_pc); 1580 // Pop frame (fixed frame-size). 1581 __ addi(R1_SP, R1_SP, (int)framesize); 1582 } 1583 1584 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1585 __ reserved_stack_check(return_pc); 1586 } 1587 1588 if (method_needs_polling) { 1589 // We need to mark the code position where the load from the safepoint 1590 // polling page was emitted as relocInfo::poll_return_type here. 1591 __ relocate(relocInfo::poll_return_type); 1592 __ load_from_polling_page(polling_page); 1593 } 1594} 1595 1596uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1597 // Variable size. Determine dynamically. 1598 return MachNode::size(ra_); 1599} 1600 1601int MachEpilogNode::reloc() const { 1602 // Return number of relocatable values contained in this instruction. 1603 return 1; // 1 for load_from_polling_page. 1604} 1605 1606const Pipeline * MachEpilogNode::pipeline() const { 1607 return MachNode::pipeline_class(); 1608} 1609 1610// This method seems to be obsolete. It is declared in machnode.hpp 1611// and defined in all *.ad files, but it is never called. Should we 1612// get rid of it? 1613int MachEpilogNode::safepoint_offset() const { 1614 assert(do_polling(), "no return for this epilog node"); 1615 return 0; 1616} 1617 1618#if 0 // TODO: PPC port 1619void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1620 MacroAssembler _masm(&cbuf); 1621 if (LoadPollAddressFromThread) { 1622 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1623 } else { 1624 _masm.nop(); 1625 } 1626} 1627 1628uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1629 if (LoadPollAddressFromThread) { 1630 return 4; 1631 } else { 1632 return 4; 1633 } 1634} 1635 1636#ifndef PRODUCT 1637void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1638 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1639} 1640#endif 1641 1642const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1643 return RSCRATCH1_BITS64_REG_mask(); 1644} 1645#endif // PPC port 1646 1647// ============================================================================= 1648 1649// Figure out which register class each belongs in: rc_int, rc_float, rc_vs or 1650// rc_stack. 1651enum RC { rc_bad, rc_int, rc_float, rc_vs, rc_stack }; 1652 1653static enum RC rc_class(OptoReg::Name reg) { 1654 // Return the register class for the given register. The given register 1655 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1656 // enumeration in adGlobals_ppc.hpp. 1657 1658 if (reg == OptoReg::Bad) return rc_bad; 1659 1660 // We have 64 integer register halves, starting at index 0. 1661 if (reg < 64) return rc_int; 1662 1663 // We have 64 floating-point register halves, starting at index 64. 1664 if (reg < 64+64) return rc_float; 1665 1666 // We have 64 vector-scalar registers, starting at index 128. 1667 if (reg < 64+64+64) return rc_vs; 1668 1669 // Between float regs & stack are the flags regs. 1670 assert(OptoReg::is_stack(reg) || reg < 64+64+64, "blow up if spilling flags"); 1671 1672 return rc_stack; 1673} 1674 1675static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1676 bool do_print, Compile* C, outputStream *st) { 1677 1678 assert(opcode == Assembler::LD_OPCODE || 1679 opcode == Assembler::STD_OPCODE || 1680 opcode == Assembler::LWZ_OPCODE || 1681 opcode == Assembler::STW_OPCODE || 1682 opcode == Assembler::LFD_OPCODE || 1683 opcode == Assembler::STFD_OPCODE || 1684 opcode == Assembler::LFS_OPCODE || 1685 opcode == Assembler::STFS_OPCODE, 1686 "opcode not supported"); 1687 1688 if (cbuf) { 1689 int d = 1690 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1691 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1692 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1693 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1694 } 1695#ifndef PRODUCT 1696 else if (do_print) { 1697 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1698 op_str, 1699 Matcher::regName[reg], 1700 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1701 } 1702#endif 1703 return 4; // size 1704} 1705 1706uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1707 Compile* C = ra_->C; 1708 1709 // Get registers to move. 1710 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1711 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1712 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1713 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1714 1715 enum RC src_hi_rc = rc_class(src_hi); 1716 enum RC src_lo_rc = rc_class(src_lo); 1717 enum RC dst_hi_rc = rc_class(dst_hi); 1718 enum RC dst_lo_rc = rc_class(dst_lo); 1719 1720 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1721 if (src_hi != OptoReg::Bad) 1722 assert((src_lo&1)==0 && src_lo+1==src_hi && 1723 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1724 "expected aligned-adjacent pairs"); 1725 // Generate spill code! 1726 int size = 0; 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return size; // Self copy, no move. 1730 1731 if (bottom_type()->isa_vect() != NULL && ideal_reg() == Op_VecX) { 1732 // Memory->Memory Spill. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 int src_offset = ra_->reg2offset(src_lo); 1735 int dst_offset = ra_->reg2offset(dst_lo); 1736 if (cbuf) { 1737 MacroAssembler _masm(cbuf); 1738 __ ld(R0, src_offset, R1_SP); 1739 __ std(R0, dst_offset, R1_SP); 1740 __ ld(R0, src_offset+8, R1_SP); 1741 __ std(R0, dst_offset+8, R1_SP); 1742 } 1743 size += 16; 1744 } 1745 // VectorSRegister->Memory Spill. 1746 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_stack) { 1747 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1748 int dst_offset = ra_->reg2offset(dst_lo); 1749 if (cbuf) { 1750 MacroAssembler _masm(cbuf); 1751 __ addi(R0, R1_SP, dst_offset); 1752 __ stxvd2x(Rsrc, R0); 1753 } 1754 size += 8; 1755 } 1756 // Memory->VectorSRegister Spill. 1757 else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vs) { 1758 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1759 int src_offset = ra_->reg2offset(src_lo); 1760 if (cbuf) { 1761 MacroAssembler _masm(cbuf); 1762 __ addi(R0, R1_SP, src_offset); 1763 __ lxvd2x(Rdst, R0); 1764 } 1765 size += 8; 1766 } 1767 // VectorSRegister->VectorSRegister. 1768 else if (src_lo_rc == rc_vs && dst_lo_rc == rc_vs) { 1769 VectorSRegister Rsrc = as_VectorSRegister(Matcher::_regEncode[src_lo]); 1770 VectorSRegister Rdst = as_VectorSRegister(Matcher::_regEncode[dst_lo]); 1771 if (cbuf) { 1772 MacroAssembler _masm(cbuf); 1773 __ xxlor(Rdst, Rsrc, Rsrc); 1774 } 1775 size += 4; 1776 } 1777 else { 1778 ShouldNotReachHere(); // No VSR spill. 1779 } 1780 return size; 1781 } 1782 1783 // -------------------------------------- 1784 // Memory->Memory Spill. Use R0 to hold the value. 1785 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1786 int src_offset = ra_->reg2offset(src_lo); 1787 int dst_offset = ra_->reg2offset(dst_lo); 1788 if (src_hi != OptoReg::Bad) { 1789 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1790 "expected same type of move for high parts"); 1791 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1792 if (!cbuf && !do_size) st->print("\n\t"); 1793 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1794 } else { 1795 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1796 if (!cbuf && !do_size) st->print("\n\t"); 1797 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1798 } 1799 return size; 1800 } 1801 1802 // -------------------------------------- 1803 // Check for float->int copy; requires a trip through memory. 1804 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1805 Unimplemented(); 1806 } 1807 1808 // -------------------------------------- 1809 // Check for integer reg-reg copy. 1810 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1811 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1812 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1813 size = (Rsrc != Rdst) ? 4 : 0; 1814 1815 if (cbuf) { 1816 MacroAssembler _masm(cbuf); 1817 if (size) { 1818 __ mr(Rdst, Rsrc); 1819 } 1820 } 1821#ifndef PRODUCT 1822 else if (!do_size) { 1823 if (size) { 1824 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1825 } else { 1826 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1827 } 1828 } 1829#endif 1830 return size; 1831 } 1832 1833 // Check for integer store. 1834 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1835 int dst_offset = ra_->reg2offset(dst_lo); 1836 if (src_hi != OptoReg::Bad) { 1837 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1838 "expected same type of move for high parts"); 1839 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1840 } else { 1841 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1842 } 1843 return size; 1844 } 1845 1846 // Check for integer load. 1847 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1848 int src_offset = ra_->reg2offset(src_lo); 1849 if (src_hi != OptoReg::Bad) { 1850 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1851 "expected same type of move for high parts"); 1852 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1853 } else { 1854 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1855 } 1856 return size; 1857 } 1858 1859 // Check for float reg-reg copy. 1860 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1861 if (cbuf) { 1862 MacroAssembler _masm(cbuf); 1863 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1864 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1865 __ fmr(Rdst, Rsrc); 1866 } 1867#ifndef PRODUCT 1868 else if (!do_size) { 1869 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1870 } 1871#endif 1872 return 4; 1873 } 1874 1875 // Check for float store. 1876 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1877 int dst_offset = ra_->reg2offset(dst_lo); 1878 if (src_hi != OptoReg::Bad) { 1879 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1880 "expected same type of move for high parts"); 1881 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1882 } else { 1883 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1884 } 1885 return size; 1886 } 1887 1888 // Check for float load. 1889 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1890 int src_offset = ra_->reg2offset(src_lo); 1891 if (src_hi != OptoReg::Bad) { 1892 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1893 "expected same type of move for high parts"); 1894 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1895 } else { 1896 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1897 } 1898 return size; 1899 } 1900 1901 // -------------------------------------------------------------------- 1902 // Check for hi bits still needing moving. Only happens for misaligned 1903 // arguments to native calls. 1904 if (src_hi == dst_hi) 1905 return size; // Self copy; no move. 1906 1907 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1908 ShouldNotReachHere(); // Unimplemented 1909 return 0; 1910} 1911 1912#ifndef PRODUCT 1913void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1914 if (!ra_) 1915 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1916 else 1917 implementation(NULL, ra_, false, st); 1918} 1919#endif 1920 1921void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1922 implementation(&cbuf, ra_, false, NULL); 1923} 1924 1925uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1926 return implementation(NULL, ra_, true, NULL); 1927} 1928 1929#if 0 // TODO: PPC port 1930ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1931#ifndef PRODUCT 1932 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1933#endif 1934 assert(ra_->node_regs_max_index() != 0, ""); 1935 1936 // Get registers to move. 1937 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1938 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1939 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1940 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1941 1942 enum RC src_lo_rc = rc_class(src_lo); 1943 enum RC dst_lo_rc = rc_class(dst_lo); 1944 1945 if (src_lo == dst_lo && src_hi == dst_hi) 1946 return ppc64Opcode_none; // Self copy, no move. 1947 1948 // -------------------------------------- 1949 // Memory->Memory Spill. Use R0 to hold the value. 1950 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1951 return ppc64Opcode_compound; 1952 } 1953 1954 // -------------------------------------- 1955 // Check for float->int copy; requires a trip through memory. 1956 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1957 Unimplemented(); 1958 } 1959 1960 // -------------------------------------- 1961 // Check for integer reg-reg copy. 1962 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1963 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1964 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1965 if (Rsrc == Rdst) { 1966 return ppc64Opcode_none; 1967 } else { 1968 return ppc64Opcode_or; 1969 } 1970 } 1971 1972 // Check for integer store. 1973 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1974 if (src_hi != OptoReg::Bad) { 1975 return ppc64Opcode_std; 1976 } else { 1977 return ppc64Opcode_stw; 1978 } 1979 } 1980 1981 // Check for integer load. 1982 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1983 if (src_hi != OptoReg::Bad) { 1984 return ppc64Opcode_ld; 1985 } else { 1986 return ppc64Opcode_lwz; 1987 } 1988 } 1989 1990 // Check for float reg-reg copy. 1991 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1992 return ppc64Opcode_fmr; 1993 } 1994 1995 // Check for float store. 1996 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1997 if (src_hi != OptoReg::Bad) { 1998 return ppc64Opcode_stfd; 1999 } else { 2000 return ppc64Opcode_stfs; 2001 } 2002 } 2003 2004 // Check for float load. 2005 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 2006 if (src_hi != OptoReg::Bad) { 2007 return ppc64Opcode_lfd; 2008 } else { 2009 return ppc64Opcode_lfs; 2010 } 2011 } 2012 2013 // -------------------------------------------------------------------- 2014 // Check for hi bits still needing moving. Only happens for misaligned 2015 // arguments to native calls. 2016 if (src_hi == dst_hi) { 2017 return ppc64Opcode_none; // Self copy; no move. 2018 } 2019 2020 ShouldNotReachHere(); 2021 return ppc64Opcode_undefined; 2022} 2023#endif // PPC port 2024 2025#ifndef PRODUCT 2026void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2027 st->print("NOP \t// %d nops to pad for loops.", _count); 2028} 2029#endif 2030 2031void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 2032 MacroAssembler _masm(&cbuf); 2033 // _count contains the number of nops needed for padding. 2034 for (int i = 0; i < _count; i++) { 2035 __ nop(); 2036 } 2037} 2038 2039uint MachNopNode::size(PhaseRegAlloc *ra_) const { 2040 return _count * 4; 2041} 2042 2043#ifndef PRODUCT 2044void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2045 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2046 char reg_str[128]; 2047 ra_->dump_register(this, reg_str); 2048 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 2049} 2050#endif 2051 2052void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2053 MacroAssembler _masm(&cbuf); 2054 2055 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2056 int reg = ra_->get_encode(this); 2057 2058 if (Assembler::is_simm(offset, 16)) { 2059 __ addi(as_Register(reg), R1, offset); 2060 } else { 2061 ShouldNotReachHere(); 2062 } 2063} 2064 2065uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2066 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2067 return 4; 2068} 2069 2070#ifndef PRODUCT 2071void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2072 st->print_cr("---- MachUEPNode ----"); 2073 st->print_cr("..."); 2074} 2075#endif 2076 2077void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2078 // This is the unverified entry point. 2079 MacroAssembler _masm(&cbuf); 2080 2081 // Inline_cache contains a klass. 2082 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 2083 Register receiver_klass = R12_scratch2; // tmp 2084 2085 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 2086 assert(R11_scratch1 == R11, "need prologue scratch register"); 2087 2088 // Check for NULL argument if we don't have implicit null checks. 2089 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 2090 if (TrapBasedNullChecks) { 2091 __ trap_null_check(R3_ARG1); 2092 } else { 2093 Label valid; 2094 __ cmpdi(CCR0, R3_ARG1, 0); 2095 __ bne_predict_taken(CCR0, valid); 2096 // We have a null argument, branch to ic_miss_stub. 2097 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2098 relocInfo::runtime_call_type); 2099 __ bind(valid); 2100 } 2101 } 2102 // Assume argument is not NULL, load klass from receiver. 2103 __ load_klass(receiver_klass, R3_ARG1); 2104 2105 if (TrapBasedICMissChecks) { 2106 __ trap_ic_miss_check(receiver_klass, ic_klass); 2107 } else { 2108 Label valid; 2109 __ cmpd(CCR0, receiver_klass, ic_klass); 2110 __ beq_predict_taken(CCR0, valid); 2111 // We have an unexpected klass, branch to ic_miss_stub. 2112 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 2113 relocInfo::runtime_call_type); 2114 __ bind(valid); 2115 } 2116 2117 // Argument is valid and klass is as expected, continue. 2118} 2119 2120#if 0 // TODO: PPC port 2121// Optimize UEP code on z (save a load_const() call in main path). 2122int MachUEPNode::ep_offset() { 2123 return 0; 2124} 2125#endif 2126 2127uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 2128 // Variable size. Determine dynamically. 2129 return MachNode::size(ra_); 2130} 2131 2132//============================================================================= 2133 2134%} // interrupt source 2135 2136source_hpp %{ // Header information of the source block. 2137 2138class HandlerImpl { 2139 2140 public: 2141 2142 static int emit_exception_handler(CodeBuffer &cbuf); 2143 static int emit_deopt_handler(CodeBuffer& cbuf); 2144 2145 static uint size_exception_handler() { 2146 // The exception_handler is a b64_patchable. 2147 return MacroAssembler::b64_patchable_size; 2148 } 2149 2150 static uint size_deopt_handler() { 2151 // The deopt_handler is a bl64_patchable. 2152 return MacroAssembler::bl64_patchable_size; 2153 } 2154 2155}; 2156 2157%} // end source_hpp 2158 2159source %{ 2160 2161int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 2162 MacroAssembler _masm(&cbuf); 2163 2164 address base = __ start_a_stub(size_exception_handler()); 2165 if (base == NULL) return 0; // CodeBuffer::expand failed 2166 2167 int offset = __ offset(); 2168 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 2169 relocInfo::runtime_call_type); 2170 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 2171 __ end_a_stub(); 2172 2173 return offset; 2174} 2175 2176// The deopt_handler is like the exception handler, but it calls to 2177// the deoptimization blob instead of jumping to the exception blob. 2178int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 2179 MacroAssembler _masm(&cbuf); 2180 2181 address base = __ start_a_stub(size_deopt_handler()); 2182 if (base == NULL) return 0; // CodeBuffer::expand failed 2183 2184 int offset = __ offset(); 2185 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 2186 relocInfo::runtime_call_type); 2187 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 2188 __ end_a_stub(); 2189 2190 return offset; 2191} 2192 2193//============================================================================= 2194 2195// Use a frame slots bias for frameless methods if accessing the stack. 2196static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 2197 if (as_Register(reg_enc) == R1_SP) { 2198 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 2199 } 2200 return 0; 2201} 2202 2203const bool Matcher::match_rule_supported(int opcode) { 2204 if (!has_match_rule(opcode)) 2205 return false; 2206 2207 switch (opcode) { 2208 case Op_SqrtD: 2209 return VM_Version::has_fsqrt(); 2210 case Op_CountLeadingZerosI: 2211 case Op_CountLeadingZerosL: 2212 if (!UseCountLeadingZerosInstructionsPPC64) 2213 return false; 2214 break; 2215 case Op_CountTrailingZerosI: 2216 case Op_CountTrailingZerosL: 2217 if (!UseCountLeadingZerosInstructionsPPC64 && 2218 !UseCountTrailingZerosInstructionsPPC64) 2219 return false; 2220 break; 2221 2222 case Op_PopCountI: 2223 case Op_PopCountL: 2224 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2225 2226 case Op_StrComp: 2227 return SpecialStringCompareTo; 2228 case Op_StrEquals: 2229 return SpecialStringEquals; 2230 case Op_StrIndexOf: 2231 return SpecialStringIndexOf; 2232 case Op_StrIndexOfChar: 2233 return SpecialStringIndexOf; 2234 2235 case Op_Digit: 2236 case Op_LowerCase: 2237 case Op_UpperCase: 2238 case Op_Whitespace: 2239 return UseCharacterCompareIntrinsics; 2240 } 2241 2242 return true; // Per default match rules are supported. 2243} 2244 2245const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2246 2247 // TODO 2248 // identify extra cases that we might want to provide match rules for 2249 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2250 bool ret_value = match_rule_supported(opcode); 2251 // Add rules here. 2252 2253 return ret_value; // Per default match rules are supported. 2254} 2255 2256const bool Matcher::has_predicated_vectors(void) { 2257 return false; 2258} 2259 2260const int Matcher::float_pressure(int default_pressure_threshold) { 2261 return default_pressure_threshold; 2262} 2263 2264int Matcher::regnum_to_fpu_offset(int regnum) { 2265 // No user for this method? 2266 Unimplemented(); 2267 return 999; 2268} 2269 2270const bool Matcher::convL2FSupported(void) { 2271 // fcfids can do the conversion (>= Power7). 2272 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2273 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2274} 2275 2276// Vector width in bytes. 2277const int Matcher::vector_width_in_bytes(BasicType bt) { 2278 if (SuperwordUseVSX) { 2279 assert(MaxVectorSize == 16, ""); 2280 return 16; 2281 } else { 2282 assert(MaxVectorSize == 8, ""); 2283 return 8; 2284 } 2285} 2286 2287// Vector ideal reg. 2288const uint Matcher::vector_ideal_reg(int size) { 2289 if (SuperwordUseVSX) { 2290 assert(MaxVectorSize == 16 && size == 16, ""); 2291 return Op_VecX; 2292 } else { 2293 assert(MaxVectorSize == 8 && size == 8, ""); 2294 return Op_RegL; 2295 } 2296} 2297 2298const uint Matcher::vector_shift_count_ideal_reg(int size) { 2299 fatal("vector shift is not supported"); 2300 return Node::NotAMachineReg; 2301} 2302 2303// Limits on vector size (number of elements) loaded into vector. 2304const int Matcher::max_vector_size(const BasicType bt) { 2305 assert(is_java_primitive(bt), "only primitive type vectors"); 2306 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2307} 2308 2309const int Matcher::min_vector_size(const BasicType bt) { 2310 return max_vector_size(bt); // Same as max. 2311} 2312 2313// PPC implementation uses VSX load/store instructions (if 2314// SuperwordUseVSX) which support 4 byte but not arbitrary alignment 2315const bool Matcher::misaligned_vectors_ok() { 2316 return false; 2317} 2318 2319// PPC AES support not yet implemented 2320const bool Matcher::pass_original_key_for_aes() { 2321 return false; 2322} 2323 2324// RETURNS: whether this branch offset is short enough that a short 2325// branch can be used. 2326// 2327// If the platform does not provide any short branch variants, then 2328// this method should return `false' for offset 0. 2329// 2330// `Compile::Fill_buffer' will decide on basis of this information 2331// whether to do the pass `Compile::Shorten_branches' at all. 2332// 2333// And `Compile::Shorten_branches' will decide on basis of this 2334// information whether to replace particular branch sites by short 2335// ones. 2336bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2337 // Is the offset within the range of a ppc64 pc relative branch? 2338 bool b; 2339 2340 const int safety_zone = 3 * BytesPerInstWord; 2341 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2342 29 - 16 + 1 + 2); 2343 return b; 2344} 2345 2346const bool Matcher::isSimpleConstant64(jlong value) { 2347 // Probably always true, even if a temp register is required. 2348 return true; 2349} 2350/* TODO: PPC port 2351// Make a new machine dependent decode node (with its operands). 2352MachTypeNode *Matcher::make_decode_node() { 2353 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2354 "This method is only implemented for unscaled cOops mode so far"); 2355 MachTypeNode *decode = new decodeN_unscaledNode(); 2356 decode->set_opnd_array(0, new iRegPdstOper()); 2357 decode->set_opnd_array(1, new iRegNsrcOper()); 2358 return decode; 2359} 2360*/ 2361 2362// false => size gets scaled to BytesPerLong, ok. 2363const bool Matcher::init_array_count_is_in_bytes = false; 2364 2365// Use conditional move (CMOVL) on Power7. 2366const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2367 2368// Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2369// fsel doesn't accept a condition register as input, so this would be slightly different. 2370const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2371 2372// Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2373const bool Matcher::require_postalloc_expand = true; 2374 2375// Do we need to mask the count passed to shift instructions or does 2376// the cpu only look at the lower 5/6 bits anyway? 2377// PowerPC requires masked shift counts. 2378const bool Matcher::need_masked_shift_count = true; 2379 2380// This affects two different things: 2381// - how Decode nodes are matched 2382// - how ImplicitNullCheck opportunities are recognized 2383// If true, the matcher will try to remove all Decodes and match them 2384// (as operands) into nodes. NullChecks are not prepared to deal with 2385// Decodes by final_graph_reshaping(). 2386// If false, final_graph_reshaping() forces the decode behind the Cmp 2387// for a NullCheck. The matcher matches the Decode node into a register. 2388// Implicit_null_check optimization moves the Decode along with the 2389// memory operation back up before the NullCheck. 2390bool Matcher::narrow_oop_use_complex_address() { 2391 // TODO: PPC port if (MatchDecodeNodes) return true; 2392 return false; 2393} 2394 2395bool Matcher::narrow_klass_use_complex_address() { 2396 NOT_LP64(ShouldNotCallThis()); 2397 assert(UseCompressedClassPointers, "only for compressed klass code"); 2398 // TODO: PPC port if (MatchDecodeNodes) return true; 2399 return false; 2400} 2401 2402bool Matcher::const_oop_prefer_decode() { 2403 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2404 return Universe::narrow_oop_base() == NULL; 2405} 2406 2407bool Matcher::const_klass_prefer_decode() { 2408 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2409 return Universe::narrow_klass_base() == NULL; 2410} 2411 2412// Is it better to copy float constants, or load them directly from memory? 2413// Intel can load a float constant from a direct address, requiring no 2414// extra registers. Most RISCs will have to materialize an address into a 2415// register first, so they would do better to copy the constant from stack. 2416const bool Matcher::rematerialize_float_constants = false; 2417 2418// If CPU can load and store mis-aligned doubles directly then no fixup is 2419// needed. Else we split the double into 2 integer pieces and move it 2420// piece-by-piece. Only happens when passing doubles into C code as the 2421// Java calling convention forces doubles to be aligned. 2422const bool Matcher::misaligned_doubles_ok = true; 2423 2424void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2425 Unimplemented(); 2426} 2427 2428// Advertise here if the CPU requires explicit rounding operations 2429// to implement the UseStrictFP mode. 2430const bool Matcher::strict_fp_requires_explicit_rounding = false; 2431 2432// Do floats take an entire double register or just half? 2433// 2434// A float occupies a ppc64 double register. For the allocator, a 2435// ppc64 double register appears as a pair of float registers. 2436bool Matcher::float_in_double() { return true; } 2437 2438// Do ints take an entire long register or just half? 2439// The relevant question is how the int is callee-saved: 2440// the whole long is written but de-opt'ing will have to extract 2441// the relevant 32 bits. 2442const bool Matcher::int_in_long = true; 2443 2444// Constants for c2c and c calling conventions. 2445 2446const MachRegisterNumbers iarg_reg[8] = { 2447 R3_num, R4_num, R5_num, R6_num, 2448 R7_num, R8_num, R9_num, R10_num 2449}; 2450 2451const MachRegisterNumbers farg_reg[13] = { 2452 F1_num, F2_num, F3_num, F4_num, 2453 F5_num, F6_num, F7_num, F8_num, 2454 F9_num, F10_num, F11_num, F12_num, 2455 F13_num 2456}; 2457 2458const MachRegisterNumbers vsarg_reg[64] = { 2459 VSR0_num, VSR1_num, VSR2_num, VSR3_num, 2460 VSR4_num, VSR5_num, VSR6_num, VSR7_num, 2461 VSR8_num, VSR9_num, VSR10_num, VSR11_num, 2462 VSR12_num, VSR13_num, VSR14_num, VSR15_num, 2463 VSR16_num, VSR17_num, VSR18_num, VSR19_num, 2464 VSR20_num, VSR21_num, VSR22_num, VSR23_num, 2465 VSR24_num, VSR23_num, VSR24_num, VSR25_num, 2466 VSR28_num, VSR29_num, VSR30_num, VSR31_num, 2467 VSR32_num, VSR33_num, VSR34_num, VSR35_num, 2468 VSR36_num, VSR37_num, VSR38_num, VSR39_num, 2469 VSR40_num, VSR41_num, VSR42_num, VSR43_num, 2470 VSR44_num, VSR45_num, VSR46_num, VSR47_num, 2471 VSR48_num, VSR49_num, VSR50_num, VSR51_num, 2472 VSR52_num, VSR53_num, VSR54_num, VSR55_num, 2473 VSR56_num, VSR57_num, VSR58_num, VSR59_num, 2474 VSR60_num, VSR61_num, VSR62_num, VSR63_num 2475}; 2476 2477const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2478 2479const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2480 2481const int num_vsarg_registers = sizeof(vsarg_reg) / sizeof(vsarg_reg[0]); 2482 2483// Return whether or not this register is ever used as an argument. This 2484// function is used on startup to build the trampoline stubs in generateOptoStub. 2485// Registers not mentioned will be killed by the VM call in the trampoline, and 2486// arguments in those registers not be available to the callee. 2487bool Matcher::can_be_java_arg(int reg) { 2488 // We return true for all registers contained in iarg_reg[] and 2489 // farg_reg[] and their virtual halves. 2490 // We must include the virtual halves in order to get STDs and LDs 2491 // instead of STWs and LWs in the trampoline stubs. 2492 2493 if ( reg == R3_num || reg == R3_H_num 2494 || reg == R4_num || reg == R4_H_num 2495 || reg == R5_num || reg == R5_H_num 2496 || reg == R6_num || reg == R6_H_num 2497 || reg == R7_num || reg == R7_H_num 2498 || reg == R8_num || reg == R8_H_num 2499 || reg == R9_num || reg == R9_H_num 2500 || reg == R10_num || reg == R10_H_num) 2501 return true; 2502 2503 if ( reg == F1_num || reg == F1_H_num 2504 || reg == F2_num || reg == F2_H_num 2505 || reg == F3_num || reg == F3_H_num 2506 || reg == F4_num || reg == F4_H_num 2507 || reg == F5_num || reg == F5_H_num 2508 || reg == F6_num || reg == F6_H_num 2509 || reg == F7_num || reg == F7_H_num 2510 || reg == F8_num || reg == F8_H_num 2511 || reg == F9_num || reg == F9_H_num 2512 || reg == F10_num || reg == F10_H_num 2513 || reg == F11_num || reg == F11_H_num 2514 || reg == F12_num || reg == F12_H_num 2515 || reg == F13_num || reg == F13_H_num) 2516 return true; 2517 2518 return false; 2519} 2520 2521bool Matcher::is_spillable_arg(int reg) { 2522 return can_be_java_arg(reg); 2523} 2524 2525bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2526 return false; 2527} 2528 2529// Register for DIVI projection of divmodI. 2530RegMask Matcher::divI_proj_mask() { 2531 ShouldNotReachHere(); 2532 return RegMask(); 2533} 2534 2535// Register for MODI projection of divmodI. 2536RegMask Matcher::modI_proj_mask() { 2537 ShouldNotReachHere(); 2538 return RegMask(); 2539} 2540 2541// Register for DIVL projection of divmodL. 2542RegMask Matcher::divL_proj_mask() { 2543 ShouldNotReachHere(); 2544 return RegMask(); 2545} 2546 2547// Register for MODL projection of divmodL. 2548RegMask Matcher::modL_proj_mask() { 2549 ShouldNotReachHere(); 2550 return RegMask(); 2551} 2552 2553const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2554 return RegMask(); 2555} 2556 2557const bool Matcher::convi2l_type_required = true; 2558 2559%} 2560 2561//----------ENCODING BLOCK----------------------------------------------------- 2562// This block specifies the encoding classes used by the compiler to output 2563// byte streams. Encoding classes are parameterized macros used by 2564// Machine Instruction Nodes in order to generate the bit encoding of the 2565// instruction. Operands specify their base encoding interface with the 2566// interface keyword. There are currently supported four interfaces, 2567// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2568// operand to generate a function which returns its register number when 2569// queried. CONST_INTER causes an operand to generate a function which 2570// returns the value of the constant when queried. MEMORY_INTER causes an 2571// operand to generate four functions which return the Base Register, the 2572// Index Register, the Scale Value, and the Offset Value of the operand when 2573// queried. COND_INTER causes an operand to generate six functions which 2574// return the encoding code (ie - encoding bits for the instruction) 2575// associated with each basic boolean condition for a conditional instruction. 2576// 2577// Instructions specify two basic values for encoding. Again, a function 2578// is available to check if the constant displacement is an oop. They use the 2579// ins_encode keyword to specify their encoding classes (which must be 2580// a sequence of enc_class names, and their parameters, specified in 2581// the encoding block), and they use the 2582// opcode keyword to specify, in order, their primary, secondary, and 2583// tertiary opcode. Only the opcode sections which a particular instruction 2584// needs for encoding need to be specified. 2585encode %{ 2586 enc_class enc_unimplemented %{ 2587 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2588 MacroAssembler _masm(&cbuf); 2589 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2590 %} 2591 2592 enc_class enc_untested %{ 2593#ifdef ASSERT 2594 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2595 MacroAssembler _masm(&cbuf); 2596 __ untested("Untested mach node encoding in AD file."); 2597#else 2598 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2599#endif 2600 %} 2601 2602 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2603 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2604 MacroAssembler _masm(&cbuf); 2605 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2606 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2607 %} 2608 2609 // Load acquire. 2610 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2611 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2612 MacroAssembler _masm(&cbuf); 2613 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2614 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2615 __ twi_0($dst$$Register); 2616 __ isync(); 2617 %} 2618 2619 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2620 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 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 %} 2626 2627 // Load acquire. 2628 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2629 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2630 2631 MacroAssembler _masm(&cbuf); 2632 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2633 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2634 __ twi_0($dst$$Register); 2635 __ isync(); 2636 %} 2637 2638 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2639 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 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 %} 2645 2646 // Load acquire. 2647 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2648 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2649 2650 MacroAssembler _masm(&cbuf); 2651 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2652 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2653 __ twi_0($dst$$Register); 2654 __ isync(); 2655 %} 2656 2657 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2658 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2659 MacroAssembler _masm(&cbuf); 2660 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2661 // Operand 'ds' requires 4-alignment. 2662 assert((Idisp & 0x3) == 0, "unaligned offset"); 2663 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2664 %} 2665 2666 // Load acquire. 2667 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2668 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2669 MacroAssembler _masm(&cbuf); 2670 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2671 // Operand 'ds' requires 4-alignment. 2672 assert((Idisp & 0x3) == 0, "unaligned offset"); 2673 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2674 __ twi_0($dst$$Register); 2675 __ isync(); 2676 %} 2677 2678 enc_class enc_lfd(RegF dst, memory mem) %{ 2679 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2680 MacroAssembler _masm(&cbuf); 2681 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2682 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2683 %} 2684 2685 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2686 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2687 2688 MacroAssembler _masm(&cbuf); 2689 int toc_offset = 0; 2690 2691 address const_toc_addr; 2692 // Create a non-oop constant, no relocation needed. 2693 // If it is an IC, it has a virtual_call_Relocation. 2694 const_toc_addr = __ long_constant((jlong)$src$$constant); 2695 if (const_toc_addr == NULL) { 2696 ciEnv::current()->record_out_of_memory_failure(); 2697 return; 2698 } 2699 2700 // Get the constant's TOC offset. 2701 toc_offset = __ offset_to_method_toc(const_toc_addr); 2702 2703 // Keep the current instruction offset in mind. 2704 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2705 2706 __ ld($dst$$Register, toc_offset, $toc$$Register); 2707 %} 2708 2709 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2710 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2711 2712 MacroAssembler _masm(&cbuf); 2713 2714 if (!ra_->C->in_scratch_emit_size()) { 2715 address const_toc_addr; 2716 // Create a non-oop constant, no relocation needed. 2717 // If it is an IC, it has a virtual_call_Relocation. 2718 const_toc_addr = __ long_constant((jlong)$src$$constant); 2719 if (const_toc_addr == NULL) { 2720 ciEnv::current()->record_out_of_memory_failure(); 2721 return; 2722 } 2723 2724 // Get the constant's TOC offset. 2725 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2726 // Store the toc offset of the constant. 2727 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2728 2729 // Also keep the current instruction offset in mind. 2730 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2731 } 2732 2733 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2734 %} 2735 2736%} // encode 2737 2738source %{ 2739 2740typedef struct { 2741 loadConL_hiNode *_large_hi; 2742 loadConL_loNode *_large_lo; 2743 loadConLNode *_small; 2744 MachNode *_last; 2745} loadConLNodesTuple; 2746 2747loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2748 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2749 loadConLNodesTuple nodes; 2750 2751 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2752 if (large_constant_pool) { 2753 // Create new nodes. 2754 loadConL_hiNode *m1 = new loadConL_hiNode(); 2755 loadConL_loNode *m2 = new loadConL_loNode(); 2756 2757 // inputs for new nodes 2758 m1->add_req(NULL, toc); 2759 m2->add_req(NULL, m1); 2760 2761 // operands for new nodes 2762 m1->_opnds[0] = new iRegLdstOper(); // dst 2763 m1->_opnds[1] = immSrc; // src 2764 m1->_opnds[2] = new iRegPdstOper(); // toc 2765 m2->_opnds[0] = new iRegLdstOper(); // dst 2766 m2->_opnds[1] = immSrc; // src 2767 m2->_opnds[2] = new iRegLdstOper(); // base 2768 2769 // Initialize ins_attrib TOC fields. 2770 m1->_const_toc_offset = -1; 2771 m2->_const_toc_offset_hi_node = m1; 2772 2773 // Initialize ins_attrib instruction offset. 2774 m1->_cbuf_insts_offset = -1; 2775 2776 // register allocation for new nodes 2777 ra_->set_pair(m1->_idx, reg_second, reg_first); 2778 ra_->set_pair(m2->_idx, reg_second, reg_first); 2779 2780 // Create result. 2781 nodes._large_hi = m1; 2782 nodes._large_lo = m2; 2783 nodes._small = NULL; 2784 nodes._last = nodes._large_lo; 2785 assert(m2->bottom_type()->isa_long(), "must be long"); 2786 } else { 2787 loadConLNode *m2 = new loadConLNode(); 2788 2789 // inputs for new nodes 2790 m2->add_req(NULL, toc); 2791 2792 // operands for new nodes 2793 m2->_opnds[0] = new iRegLdstOper(); // dst 2794 m2->_opnds[1] = immSrc; // src 2795 m2->_opnds[2] = new iRegPdstOper(); // toc 2796 2797 // Initialize ins_attrib instruction offset. 2798 m2->_cbuf_insts_offset = -1; 2799 2800 // register allocation for new nodes 2801 ra_->set_pair(m2->_idx, reg_second, reg_first); 2802 2803 // Create result. 2804 nodes._large_hi = NULL; 2805 nodes._large_lo = NULL; 2806 nodes._small = m2; 2807 nodes._last = nodes._small; 2808 assert(m2->bottom_type()->isa_long(), "must be long"); 2809 } 2810 2811 return nodes; 2812} 2813 2814typedef struct { 2815 loadConL_hiNode *_large_hi; 2816 loadConL_loNode *_large_lo; 2817 mtvsrdNode *_moved; 2818 xxspltdNode *_replicated; 2819 loadConLNode *_small; 2820 MachNode *_last; 2821} loadConLReplicatedNodesTuple; 2822 2823loadConLReplicatedNodesTuple loadConLReplicatedNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2824 vecXOper *dst, immI_0Oper *zero, 2825 OptoReg::Name reg_second, OptoReg::Name reg_first, 2826 OptoReg::Name reg_vec_second, OptoReg::Name reg_vec_first) { 2827 loadConLReplicatedNodesTuple nodes; 2828 2829 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2830 if (large_constant_pool) { 2831 // Create new nodes. 2832 loadConL_hiNode *m1 = new loadConL_hiNode(); 2833 loadConL_loNode *m2 = new loadConL_loNode(); 2834 mtvsrdNode *m3 = new mtvsrdNode(); 2835 xxspltdNode *m4 = new xxspltdNode(); 2836 2837 // inputs for new nodes 2838 m1->add_req(NULL, toc); 2839 m2->add_req(NULL, m1); 2840 m3->add_req(NULL, m2); 2841 m4->add_req(NULL, m3); 2842 2843 // operands for new nodes 2844 m1->_opnds[0] = new iRegLdstOper(); // dst 2845 m1->_opnds[1] = immSrc; // src 2846 m1->_opnds[2] = new iRegPdstOper(); // toc 2847 2848 m2->_opnds[0] = new iRegLdstOper(); // dst 2849 m2->_opnds[1] = immSrc; // src 2850 m2->_opnds[2] = new iRegLdstOper(); // base 2851 2852 m3->_opnds[0] = new vecXOper(); // dst 2853 m3->_opnds[1] = new iRegLdstOper(); // src 2854 2855 m4->_opnds[0] = new vecXOper(); // dst 2856 m4->_opnds[1] = new vecXOper(); // src 2857 m4->_opnds[2] = zero; 2858 2859 // Initialize ins_attrib TOC fields. 2860 m1->_const_toc_offset = -1; 2861 m2->_const_toc_offset_hi_node = m1; 2862 2863 // Initialize ins_attrib instruction offset. 2864 m1->_cbuf_insts_offset = -1; 2865 2866 // register allocation for new nodes 2867 ra_->set_pair(m1->_idx, reg_second, reg_first); 2868 ra_->set_pair(m2->_idx, reg_second, reg_first); 2869 ra_->set1(m3->_idx, reg_second); 2870 ra_->set2(m3->_idx, reg_vec_first); 2871 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2872 2873 // Create result. 2874 nodes._large_hi = m1; 2875 nodes._large_lo = m2; 2876 nodes._moved = m3; 2877 nodes._replicated = m4; 2878 nodes._small = NULL; 2879 nodes._last = nodes._replicated; 2880 assert(m2->bottom_type()->isa_long(), "must be long"); 2881 } else { 2882 loadConLNode *m2 = new loadConLNode(); 2883 mtvsrdNode *m3 = new mtvsrdNode(); 2884 xxspltdNode *m4 = new xxspltdNode(); 2885 2886 // inputs for new nodes 2887 m2->add_req(NULL, toc); 2888 2889 // operands for new nodes 2890 m2->_opnds[0] = new iRegLdstOper(); // dst 2891 m2->_opnds[1] = immSrc; // src 2892 m2->_opnds[2] = new iRegPdstOper(); // toc 2893 2894 m3->_opnds[0] = new vecXOper(); // dst 2895 m3->_opnds[1] = new iRegLdstOper(); // src 2896 2897 m4->_opnds[0] = new vecXOper(); // dst 2898 m4->_opnds[1] = new vecXOper(); // src 2899 m4->_opnds[2] = zero; 2900 2901 // Initialize ins_attrib instruction offset. 2902 m2->_cbuf_insts_offset = -1; 2903 ra_->set1(m3->_idx, reg_second); 2904 ra_->set2(m3->_idx, reg_vec_first); 2905 ra_->set_pair(m4->_idx, reg_vec_second, reg_vec_first); 2906 2907 // register allocation for new nodes 2908 ra_->set_pair(m2->_idx, reg_second, reg_first); 2909 2910 // Create result. 2911 nodes._large_hi = NULL; 2912 nodes._large_lo = NULL; 2913 nodes._small = m2; 2914 nodes._moved = m3; 2915 nodes._replicated = m4; 2916 nodes._last = nodes._replicated; 2917 assert(m2->bottom_type()->isa_long(), "must be long"); 2918 } 2919 2920 return nodes; 2921} 2922 2923%} // source 2924 2925encode %{ 2926 // Postalloc expand emitter for loading a long constant from the method's TOC. 2927 // Enc_class needed as consttanttablebase is not supported by postalloc 2928 // expand. 2929 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2930 // Create new nodes. 2931 loadConLNodesTuple loadConLNodes = 2932 loadConLNodesTuple_create(ra_, n_toc, op_src, 2933 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2934 2935 // Push new nodes. 2936 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2937 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2938 2939 // some asserts 2940 assert(nodes->length() >= 1, "must have created at least 1 node"); 2941 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2942 %} 2943 2944 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2945 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2946 2947 MacroAssembler _masm(&cbuf); 2948 int toc_offset = 0; 2949 2950 intptr_t val = $src$$constant; 2951 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2952 address const_toc_addr; 2953 if (constant_reloc == relocInfo::oop_type) { 2954 // Create an oop constant and a corresponding relocation. 2955 AddressLiteral a = __ allocate_oop_address((jobject)val); 2956 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2957 __ relocate(a.rspec()); 2958 } else if (constant_reloc == relocInfo::metadata_type) { 2959 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2960 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2961 __ relocate(a.rspec()); 2962 } else { 2963 // Create a non-oop constant, no relocation needed. 2964 const_toc_addr = __ long_constant((jlong)$src$$constant); 2965 } 2966 2967 if (const_toc_addr == NULL) { 2968 ciEnv::current()->record_out_of_memory_failure(); 2969 return; 2970 } 2971 // Get the constant's TOC offset. 2972 toc_offset = __ offset_to_method_toc(const_toc_addr); 2973 2974 __ ld($dst$$Register, toc_offset, $toc$$Register); 2975 %} 2976 2977 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2978 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2979 2980 MacroAssembler _masm(&cbuf); 2981 if (!ra_->C->in_scratch_emit_size()) { 2982 intptr_t val = $src$$constant; 2983 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2984 address const_toc_addr; 2985 if (constant_reloc == relocInfo::oop_type) { 2986 // Create an oop constant and a corresponding relocation. 2987 AddressLiteral a = __ allocate_oop_address((jobject)val); 2988 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2989 __ relocate(a.rspec()); 2990 } else if (constant_reloc == relocInfo::metadata_type) { 2991 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2992 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2993 __ relocate(a.rspec()); 2994 } else { // non-oop pointers, e.g. card mark base, heap top 2995 // Create a non-oop constant, no relocation needed. 2996 const_toc_addr = __ long_constant((jlong)$src$$constant); 2997 } 2998 2999 if (const_toc_addr == NULL) { 3000 ciEnv::current()->record_out_of_memory_failure(); 3001 return; 3002 } 3003 // Get the constant's TOC offset. 3004 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 3005 // Store the toc offset of the constant. 3006 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 3007 } 3008 3009 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 3010 %} 3011 3012 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 3013 // Enc_class needed as consttanttablebase is not supported by postalloc 3014 // expand. 3015 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 3016 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3017 if (large_constant_pool) { 3018 // Create new nodes. 3019 loadConP_hiNode *m1 = new loadConP_hiNode(); 3020 loadConP_loNode *m2 = new loadConP_loNode(); 3021 3022 // inputs for new nodes 3023 m1->add_req(NULL, n_toc); 3024 m2->add_req(NULL, m1); 3025 3026 // operands for new nodes 3027 m1->_opnds[0] = new iRegPdstOper(); // dst 3028 m1->_opnds[1] = op_src; // src 3029 m1->_opnds[2] = new iRegPdstOper(); // toc 3030 m2->_opnds[0] = new iRegPdstOper(); // dst 3031 m2->_opnds[1] = op_src; // src 3032 m2->_opnds[2] = new iRegLdstOper(); // base 3033 3034 // Initialize ins_attrib TOC fields. 3035 m1->_const_toc_offset = -1; 3036 m2->_const_toc_offset_hi_node = m1; 3037 3038 // Register allocation for new nodes. 3039 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3040 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3041 3042 nodes->push(m1); 3043 nodes->push(m2); 3044 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3045 } else { 3046 loadConPNode *m2 = new loadConPNode(); 3047 3048 // inputs for new nodes 3049 m2->add_req(NULL, n_toc); 3050 3051 // operands for new nodes 3052 m2->_opnds[0] = new iRegPdstOper(); // dst 3053 m2->_opnds[1] = op_src; // src 3054 m2->_opnds[2] = new iRegPdstOper(); // toc 3055 3056 // Register allocation for new nodes. 3057 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3058 3059 nodes->push(m2); 3060 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 3061 } 3062 %} 3063 3064 // Enc_class needed as consttanttablebase is not supported by postalloc 3065 // expand. 3066 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 3067 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3068 3069 MachNode *m2; 3070 if (large_constant_pool) { 3071 m2 = new loadConFCompNode(); 3072 } else { 3073 m2 = new loadConFNode(); 3074 } 3075 // inputs for new nodes 3076 m2->add_req(NULL, n_toc); 3077 3078 // operands for new nodes 3079 m2->_opnds[0] = op_dst; 3080 m2->_opnds[1] = op_src; 3081 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3082 3083 // register allocation for new nodes 3084 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3085 nodes->push(m2); 3086 %} 3087 3088 // Enc_class needed as consttanttablebase is not supported by postalloc 3089 // expand. 3090 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 3091 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 3092 3093 MachNode *m2; 3094 if (large_constant_pool) { 3095 m2 = new loadConDCompNode(); 3096 } else { 3097 m2 = new loadConDNode(); 3098 } 3099 // inputs for new nodes 3100 m2->add_req(NULL, n_toc); 3101 3102 // operands for new nodes 3103 m2->_opnds[0] = op_dst; 3104 m2->_opnds[1] = op_src; 3105 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 3106 3107 // register allocation for new nodes 3108 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3109 nodes->push(m2); 3110 %} 3111 3112 enc_class enc_stw(iRegIsrc src, memory mem) %{ 3113 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 3114 MacroAssembler _masm(&cbuf); 3115 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3116 __ stw($src$$Register, Idisp, $mem$$base$$Register); 3117 %} 3118 3119 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 3120 // TODO: PPC port $archOpcode(ppc64Opcode_std); 3121 MacroAssembler _masm(&cbuf); 3122 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3123 // Operand 'ds' requires 4-alignment. 3124 assert((Idisp & 0x3) == 0, "unaligned offset"); 3125 __ std($src$$Register, Idisp, $mem$$base$$Register); 3126 %} 3127 3128 enc_class enc_stfs(RegF src, memory mem) %{ 3129 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 3130 MacroAssembler _masm(&cbuf); 3131 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3132 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 3133 %} 3134 3135 enc_class enc_stfd(RegF src, memory mem) %{ 3136 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 3137 MacroAssembler _masm(&cbuf); 3138 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3139 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 3140 %} 3141 3142 // Use release_store for card-marking to ensure that previous 3143 // oop-stores are visible before the card-mark change. 3144 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 3145 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3146 // FIXME: Implement this as a cmove and use a fixed condition code 3147 // register which is written on every transition to compiled code, 3148 // e.g. in call-stub and when returning from runtime stubs. 3149 // 3150 // Proposed code sequence for the cmove implementation: 3151 // 3152 // Label skip_release; 3153 // __ beq(CCRfixed, skip_release); 3154 // __ release(); 3155 // __ bind(skip_release); 3156 // __ stb(card mark); 3157 3158 MacroAssembler _masm(&cbuf); 3159 Label skip_storestore; 3160 3161#if 0 // TODO: PPC port 3162 // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the 3163 // StoreStore barrier conditionally. 3164 __ lwz(R0, 0, $releaseFieldAddr$$Register); 3165 __ cmpwi($crx$$CondRegister, R0, 0); 3166 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 3167#endif 3168 __ li(R0, 0); 3169 __ membar(Assembler::StoreStore); 3170#if 0 // TODO: PPC port 3171 __ bind(skip_storestore); 3172#endif 3173 3174 // Do the store. 3175 if ($mem$$index == 0) { 3176 __ stb(R0, $mem$$disp, $mem$$base$$Register); 3177 } else { 3178 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 3179 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 3180 } 3181 %} 3182 3183 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 3184 3185 if (VM_Version::has_isel()) { 3186 // use isel instruction with Power 7 3187 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3188 encodeP_subNode *n_sub_base = new encodeP_subNode(); 3189 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3190 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 3191 3192 n_compare->add_req(n_region, n_src); 3193 n_compare->_opnds[0] = op_crx; 3194 n_compare->_opnds[1] = op_src; 3195 n_compare->_opnds[2] = new immL16Oper(0); 3196 3197 n_sub_base->add_req(n_region, n_src); 3198 n_sub_base->_opnds[0] = op_dst; 3199 n_sub_base->_opnds[1] = op_src; 3200 n_sub_base->_bottom_type = _bottom_type; 3201 3202 n_shift->add_req(n_region, n_sub_base); 3203 n_shift->_opnds[0] = op_dst; 3204 n_shift->_opnds[1] = op_dst; 3205 n_shift->_bottom_type = _bottom_type; 3206 3207 n_cond_set->add_req(n_region, n_compare, n_shift); 3208 n_cond_set->_opnds[0] = op_dst; 3209 n_cond_set->_opnds[1] = op_crx; 3210 n_cond_set->_opnds[2] = op_dst; 3211 n_cond_set->_bottom_type = _bottom_type; 3212 3213 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3214 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3215 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3216 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3217 3218 nodes->push(n_compare); 3219 nodes->push(n_sub_base); 3220 nodes->push(n_shift); 3221 nodes->push(n_cond_set); 3222 3223 } else { 3224 // before Power 7 3225 moveRegNode *n_move = new moveRegNode(); 3226 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 3227 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 3228 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 3229 3230 n_move->add_req(n_region, n_src); 3231 n_move->_opnds[0] = op_dst; 3232 n_move->_opnds[1] = op_src; 3233 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 3234 3235 n_compare->add_req(n_region, n_src); 3236 n_compare->add_prec(n_move); 3237 3238 n_compare->_opnds[0] = op_crx; 3239 n_compare->_opnds[1] = op_src; 3240 n_compare->_opnds[2] = new immL16Oper(0); 3241 3242 n_sub_base->add_req(n_region, n_compare, n_src); 3243 n_sub_base->_opnds[0] = op_dst; 3244 n_sub_base->_opnds[1] = op_crx; 3245 n_sub_base->_opnds[2] = op_src; 3246 n_sub_base->_bottom_type = _bottom_type; 3247 3248 n_shift->add_req(n_region, n_sub_base); 3249 n_shift->_opnds[0] = op_dst; 3250 n_shift->_opnds[1] = op_dst; 3251 n_shift->_bottom_type = _bottom_type; 3252 3253 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3254 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3255 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3256 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3257 3258 nodes->push(n_move); 3259 nodes->push(n_compare); 3260 nodes->push(n_sub_base); 3261 nodes->push(n_shift); 3262 } 3263 3264 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3265 %} 3266 3267 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 3268 3269 encodeP_subNode *n1 = new encodeP_subNode(); 3270 n1->add_req(n_region, n_src); 3271 n1->_opnds[0] = op_dst; 3272 n1->_opnds[1] = op_src; 3273 n1->_bottom_type = _bottom_type; 3274 3275 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 3276 n2->add_req(n_region, n1); 3277 n2->_opnds[0] = op_dst; 3278 n2->_opnds[1] = op_dst; 3279 n2->_bottom_type = _bottom_type; 3280 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3281 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3282 3283 nodes->push(n1); 3284 nodes->push(n2); 3285 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 3286 %} 3287 3288 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 3289 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 3290 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 3291 3292 n_compare->add_req(n_region, n_src); 3293 n_compare->_opnds[0] = op_crx; 3294 n_compare->_opnds[1] = op_src; 3295 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 3296 3297 n_shift->add_req(n_region, n_src); 3298 n_shift->_opnds[0] = op_dst; 3299 n_shift->_opnds[1] = op_src; 3300 n_shift->_bottom_type = _bottom_type; 3301 3302 if (VM_Version::has_isel()) { 3303 // use isel instruction with Power 7 3304 3305 decodeN_addNode *n_add_base = new decodeN_addNode(); 3306 n_add_base->add_req(n_region, n_shift); 3307 n_add_base->_opnds[0] = op_dst; 3308 n_add_base->_opnds[1] = op_dst; 3309 n_add_base->_bottom_type = _bottom_type; 3310 3311 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 3312 n_cond_set->add_req(n_region, n_compare, n_add_base); 3313 n_cond_set->_opnds[0] = op_dst; 3314 n_cond_set->_opnds[1] = op_crx; 3315 n_cond_set->_opnds[2] = op_dst; 3316 n_cond_set->_bottom_type = _bottom_type; 3317 3318 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3319 ra_->set_oop(n_cond_set, true); 3320 3321 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3322 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3323 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3324 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3325 3326 nodes->push(n_compare); 3327 nodes->push(n_shift); 3328 nodes->push(n_add_base); 3329 nodes->push(n_cond_set); 3330 3331 } else { 3332 // before Power 7 3333 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 3334 3335 n_add_base->add_req(n_region, n_compare, n_shift); 3336 n_add_base->_opnds[0] = op_dst; 3337 n_add_base->_opnds[1] = op_crx; 3338 n_add_base->_opnds[2] = op_dst; 3339 n_add_base->_bottom_type = _bottom_type; 3340 3341 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3342 ra_->set_oop(n_add_base, true); 3343 3344 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3345 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 3346 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3347 3348 nodes->push(n_compare); 3349 nodes->push(n_shift); 3350 nodes->push(n_add_base); 3351 } 3352 %} 3353 3354 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 3355 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 3356 n1->add_req(n_region, n_src); 3357 n1->_opnds[0] = op_dst; 3358 n1->_opnds[1] = op_src; 3359 n1->_bottom_type = _bottom_type; 3360 3361 decodeN_addNode *n2 = new decodeN_addNode(); 3362 n2->add_req(n_region, n1); 3363 n2->_opnds[0] = op_dst; 3364 n2->_opnds[1] = op_dst; 3365 n2->_bottom_type = _bottom_type; 3366 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3367 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3368 3369 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3370 ra_->set_oop(n2, true); 3371 3372 nodes->push(n1); 3373 nodes->push(n2); 3374 %} 3375 3376 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3377 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3378 3379 MacroAssembler _masm(&cbuf); 3380 int cc = $cmp$$cmpcode; 3381 int flags_reg = $crx$$reg; 3382 Label done; 3383 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3384 // Branch if not (cmp crx). 3385 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3386 __ mr($dst$$Register, $src$$Register); 3387 // TODO PPC port __ endgroup_if_needed(_size == 12); 3388 __ bind(done); 3389 %} 3390 3391 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3392 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3393 3394 MacroAssembler _masm(&cbuf); 3395 Label done; 3396 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3397 // Branch if not (cmp crx). 3398 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3399 __ li($dst$$Register, $src$$constant); 3400 // TODO PPC port __ endgroup_if_needed(_size == 12); 3401 __ bind(done); 3402 %} 3403 3404 // This enc_class is needed so that scheduler gets proper 3405 // input mapping for latency computation. 3406 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3407 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3408 MacroAssembler _masm(&cbuf); 3409 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3410 %} 3411 3412 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3413 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3414 3415 MacroAssembler _masm(&cbuf); 3416 3417 Label done; 3418 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3419 __ li($dst$$Register, $zero$$constant); 3420 __ beq($crx$$CondRegister, done); 3421 __ li($dst$$Register, $notzero$$constant); 3422 __ bind(done); 3423 %} 3424 3425 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3426 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3427 3428 MacroAssembler _masm(&cbuf); 3429 3430 Label done; 3431 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3432 __ li($dst$$Register, $zero$$constant); 3433 __ beq($crx$$CondRegister, done); 3434 __ li($dst$$Register, $notzero$$constant); 3435 __ bind(done); 3436 %} 3437 3438 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3439 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3440 3441 MacroAssembler _masm(&cbuf); 3442 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3443 Label done; 3444 __ bso($crx$$CondRegister, done); 3445 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3446 // TODO PPC port __ endgroup_if_needed(_size == 12); 3447 __ bind(done); 3448 %} 3449 3450 enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 3451 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3452 3453 MacroAssembler _masm(&cbuf); 3454 Label done; 3455 __ bso($crx$$CondRegister, done); 3456 __ mffprd($dst$$Register, $src$$FloatRegister); 3457 // TODO PPC port __ endgroup_if_needed(_size == 12); 3458 __ bind(done); 3459 %} 3460 3461 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3462 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3463 3464 MacroAssembler _masm(&cbuf); 3465 Label d; // dummy 3466 __ bind(d); 3467 Label* p = ($lbl$$label); 3468 // `p' is `NULL' when this encoding class is used only to 3469 // determine the size of the encoded instruction. 3470 Label& l = (NULL == p)? d : *(p); 3471 int cc = $cmp$$cmpcode; 3472 int flags_reg = $crx$$reg; 3473 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3474 int bhint = Assembler::bhintNoHint; 3475 3476 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3477 if (_prob <= PROB_NEVER) { 3478 bhint = Assembler::bhintIsNotTaken; 3479 } else if (_prob >= PROB_ALWAYS) { 3480 bhint = Assembler::bhintIsTaken; 3481 } 3482 } 3483 3484 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3485 cc_to_biint(cc, flags_reg), 3486 l); 3487 %} 3488 3489 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3490 // The scheduler doesn't know about branch shortening, so we set the opcode 3491 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3492 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3493 3494 MacroAssembler _masm(&cbuf); 3495 Label d; // dummy 3496 __ bind(d); 3497 Label* p = ($lbl$$label); 3498 // `p' is `NULL' when this encoding class is used only to 3499 // determine the size of the encoded instruction. 3500 Label& l = (NULL == p)? d : *(p); 3501 int cc = $cmp$$cmpcode; 3502 int flags_reg = $crx$$reg; 3503 int bhint = Assembler::bhintNoHint; 3504 3505 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3506 if (_prob <= PROB_NEVER) { 3507 bhint = Assembler::bhintIsNotTaken; 3508 } else if (_prob >= PROB_ALWAYS) { 3509 bhint = Assembler::bhintIsTaken; 3510 } 3511 } 3512 3513 // Tell the conditional far branch to optimize itself when being relocated. 3514 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3515 cc_to_biint(cc, flags_reg), 3516 l, 3517 MacroAssembler::bc_far_optimize_on_relocate); 3518 %} 3519 3520 // Branch used with Power6 scheduling (can be shortened without changing the node). 3521 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3522 // The scheduler doesn't know about branch shortening, so we set the opcode 3523 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3524 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3525 3526 MacroAssembler _masm(&cbuf); 3527 Label d; // dummy 3528 __ bind(d); 3529 Label* p = ($lbl$$label); 3530 // `p' is `NULL' when this encoding class is used only to 3531 // determine the size of the encoded instruction. 3532 Label& l = (NULL == p)? d : *(p); 3533 int cc = $cmp$$cmpcode; 3534 int flags_reg = $crx$$reg; 3535 int bhint = Assembler::bhintNoHint; 3536 3537 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3538 if (_prob <= PROB_NEVER) { 3539 bhint = Assembler::bhintIsNotTaken; 3540 } else if (_prob >= PROB_ALWAYS) { 3541 bhint = Assembler::bhintIsTaken; 3542 } 3543 } 3544 3545#if 0 // TODO: PPC port 3546 if (_size == 8) { 3547 // Tell the conditional far branch to optimize itself when being relocated. 3548 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3549 cc_to_biint(cc, flags_reg), 3550 l, 3551 MacroAssembler::bc_far_optimize_on_relocate); 3552 } else { 3553 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3554 cc_to_biint(cc, flags_reg), 3555 l); 3556 } 3557#endif 3558 Unimplemented(); 3559 %} 3560 3561 // Postalloc expand emitter for loading a replicatef float constant from 3562 // the method's TOC. 3563 // Enc_class needed as consttanttablebase is not supported by postalloc 3564 // expand. 3565 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3566 // Create new nodes. 3567 3568 // Make an operand with the bit pattern to load as float. 3569 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3570 3571 loadConLNodesTuple loadConLNodes = 3572 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3573 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3574 3575 // Push new nodes. 3576 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3577 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3578 3579 assert(nodes->length() >= 1, "must have created at least 1 node"); 3580 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3581 %} 3582 3583 enc_class postalloc_expand_load_replF_constant_vsx(vecX dst, immF src, iRegLdst toc, iRegLdst tmp) %{ 3584 // Create new nodes. 3585 3586 // Make an operand with the bit pattern to load as float. 3587 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3588 immI_0Oper *op_zero = new immI_0Oper(0); 3589 3590 loadConLReplicatedNodesTuple loadConLNodes = 3591 loadConLReplicatedNodesTuple_create(C, ra_, n_toc, op_repl, op_dst, op_zero, 3592 ra_->get_reg_second(n_tmp), ra_->get_reg_first(n_tmp), 3593 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3594 3595 // Push new nodes. 3596 if (loadConLNodes._large_hi) { nodes->push(loadConLNodes._large_hi); } 3597 if (loadConLNodes._large_lo) { nodes->push(loadConLNodes._large_lo); } 3598 if (loadConLNodes._moved) { nodes->push(loadConLNodes._moved); } 3599 if (loadConLNodes._last) { nodes->push(loadConLNodes._last); } 3600 3601 assert(nodes->length() >= 1, "must have created at least 1 node"); 3602 %} 3603 3604 // This enc_class is needed so that scheduler gets proper 3605 // input mapping for latency computation. 3606 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3607 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3608 // Fake operand dst needed for PPC scheduler. 3609 assert($dst$$constant == 0x0, "dst must be 0x0"); 3610 3611 MacroAssembler _masm(&cbuf); 3612 // Mark the code position where the load from the safepoint 3613 // polling page was emitted as relocInfo::poll_type. 3614 __ relocate(relocInfo::poll_type); 3615 __ load_from_polling_page($poll$$Register); 3616 %} 3617 3618 // A Java static call or a runtime call. 3619 // 3620 // Branch-and-link relative to a trampoline. 3621 // The trampoline loads the target address and does a long branch to there. 3622 // In case we call java, the trampoline branches to a interpreter_stub 3623 // which loads the inline cache and the real call target from the constant pool. 3624 // 3625 // This basically looks like this: 3626 // 3627 // >>>> consts -+ -+ 3628 // | |- offset1 3629 // [call target1] | <-+ 3630 // [IC cache] |- offset2 3631 // [call target2] <--+ 3632 // 3633 // <<<< consts 3634 // >>>> insts 3635 // 3636 // bl offset16 -+ -+ ??? // How many bits available? 3637 // | | 3638 // <<<< insts | | 3639 // >>>> stubs | | 3640 // | |- trampoline_stub_Reloc 3641 // trampoline stub: | <-+ 3642 // r2 = toc | 3643 // r2 = [r2 + offset1] | // Load call target1 from const section 3644 // mtctr r2 | 3645 // bctr |- static_stub_Reloc 3646 // comp_to_interp_stub: <---+ 3647 // r1 = toc 3648 // ICreg = [r1 + IC_offset] // Load IC from const section 3649 // r1 = [r1 + offset2] // Load call target2 from const section 3650 // mtctr r1 3651 // bctr 3652 // 3653 // <<<< stubs 3654 // 3655 // The call instruction in the code either 3656 // - Branches directly to a compiled method if the offset is encodable in instruction. 3657 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3658 // - Branches to the compiled_to_interp stub if the target is interpreted. 3659 // 3660 // Further there are three relocations from the loads to the constants in 3661 // the constant section. 3662 // 3663 // Usage of r1 and r2 in the stubs allows to distinguish them. 3664 enc_class enc_java_static_call(method meth) %{ 3665 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3666 3667 MacroAssembler _masm(&cbuf); 3668 address entry_point = (address)$meth$$method; 3669 3670 if (!_method) { 3671 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3672 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3673 } else { 3674 // Remember the offset not the address. 3675 const int start_offset = __ offset(); 3676 3677 // The trampoline stub. 3678 // No entry point given, use the current pc. 3679 // Make sure branch fits into 3680 if (entry_point == 0) entry_point = __ pc(); 3681 3682 // Put the entry point as a constant into the constant pool. 3683 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3684 if (entry_point_toc_addr == NULL) { 3685 ciEnv::current()->record_out_of_memory_failure(); 3686 return; 3687 } 3688 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3689 3690 // Emit the trampoline stub which will be related to the branch-and-link below. 3691 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3692 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3693 int method_index = resolved_method_index(cbuf); 3694 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3695 : static_call_Relocation::spec(method_index)); 3696 3697 // The real call. 3698 // Note: At this point we do not have the address of the trampoline 3699 // stub, and the entry point might be too far away for bl, so __ pc() 3700 // serves as dummy and the bl will be patched later. 3701 cbuf.set_insts_mark(); 3702 __ bl(__ pc()); // Emits a relocation. 3703 3704 // The stub for call to interpreter. 3705 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3706 if (stub == NULL) { 3707 ciEnv::current()->record_failure("CodeCache is full"); 3708 return; 3709 } 3710 } 3711 %} 3712 3713 // Second node of expanded dynamic call - the call. 3714 enc_class enc_java_dynamic_call_sched(method meth) %{ 3715 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3716 3717 MacroAssembler _masm(&cbuf); 3718 3719 if (!ra_->C->in_scratch_emit_size()) { 3720 // Create a call trampoline stub for the given method. 3721 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3722 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3723 if (entry_point_const == NULL) { 3724 ciEnv::current()->record_out_of_memory_failure(); 3725 return; 3726 } 3727 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3728 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3729 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3730 3731 // Build relocation at call site with ic position as data. 3732 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3733 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3734 "must have one, but can't have both"); 3735 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3736 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3737 "must contain instruction offset"); 3738 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3739 ? _load_ic_hi_node->_cbuf_insts_offset 3740 : _load_ic_node->_cbuf_insts_offset; 3741 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3742 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3743 "should be load from TOC"); 3744 int method_index = resolved_method_index(cbuf); 3745 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3746 } 3747 3748 // At this point I do not have the address of the trampoline stub, 3749 // and the entry point might be too far away for bl. Pc() serves 3750 // as dummy and bl will be patched later. 3751 __ bl((address) __ pc()); 3752 %} 3753 3754 // postalloc expand emitter for virtual calls. 3755 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3756 3757 // Create the nodes for loading the IC from the TOC. 3758 loadConLNodesTuple loadConLNodes_IC = 3759 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3760 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3761 3762 // Create the call node. 3763 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3764 call->_method_handle_invoke = _method_handle_invoke; 3765 call->_vtable_index = _vtable_index; 3766 call->_method = _method; 3767 call->_bci = _bci; 3768 call->_optimized_virtual = _optimized_virtual; 3769 call->_tf = _tf; 3770 call->_entry_point = _entry_point; 3771 call->_cnt = _cnt; 3772 call->_argsize = _argsize; 3773 call->_oop_map = _oop_map; 3774 call->_jvms = _jvms; 3775 call->_jvmadj = _jvmadj; 3776 call->_in_rms = _in_rms; 3777 call->_nesting = _nesting; 3778 call->_override_symbolic_info = _override_symbolic_info; 3779 3780 // New call needs all inputs of old call. 3781 // Req... 3782 for (uint i = 0; i < req(); ++i) { 3783 // The expanded node does not need toc any more. 3784 // Add the inline cache constant here instead. This expresses the 3785 // register of the inline cache must be live at the call. 3786 // Else we would have to adapt JVMState by -1. 3787 if (i == mach_constant_base_node_input()) { 3788 call->add_req(loadConLNodes_IC._last); 3789 } else { 3790 call->add_req(in(i)); 3791 } 3792 } 3793 // ...as well as prec 3794 for (uint i = req(); i < len(); ++i) { 3795 call->add_prec(in(i)); 3796 } 3797 3798 // Remember nodes loading the inline cache into r19. 3799 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3800 call->_load_ic_node = loadConLNodes_IC._small; 3801 3802 // Operands for new nodes. 3803 call->_opnds[0] = _opnds[0]; 3804 call->_opnds[1] = _opnds[1]; 3805 3806 // Only the inline cache is associated with a register. 3807 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3808 3809 // Push new nodes. 3810 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3811 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3812 nodes->push(call); 3813 %} 3814 3815 // Compound version of call dynamic 3816 // Toc is only passed so that it can be used in ins_encode statement. 3817 // In the code we have to use $constanttablebase. 3818 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3820 MacroAssembler _masm(&cbuf); 3821 int start_offset = __ offset(); 3822 3823 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3824 3825 int vtable_index = this->_vtable_index; 3826 if (vtable_index < 0) { 3827 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3828 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3829 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3830 3831 // Virtual call relocation will point to ic load. 3832 address virtual_call_meta_addr = __ pc(); 3833 // Load a clear inline cache. 3834 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3835 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3836 if (!success) { 3837 ciEnv::current()->record_out_of_memory_failure(); 3838 return; 3839 } 3840 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3841 // to determine who we intended to call. 3842 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3843 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3844 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3845 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3846 } else { 3847 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3848 // Go thru the vtable. Get receiver klass. Receiver already 3849 // checked for non-null. If we'll go thru a C2I adapter, the 3850 // interpreter expects method in R19_method. 3851 3852 __ load_klass(R11_scratch1, R3); 3853 3854 int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes(); 3855 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3856 __ li(R19_method, v_off); 3857 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3858 // NOTE: for vtable dispatches, the vtable entry will never be 3859 // null. However it may very well end up in handle_wrong_method 3860 // if the method is abstract for the particular class. 3861 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3862 // Call target. Either compiled code or C2I adapter. 3863 __ mtctr(R11_scratch1); 3864 __ bctrl(); 3865 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3866 "Fix constant in ret_addr_offset(), expected %d", __ offset() - start_offset); 3867 } 3868 %} 3869 3870 // a runtime call 3871 enc_class enc_java_to_runtime_call (method meth) %{ 3872 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3873 3874 MacroAssembler _masm(&cbuf); 3875 const address start_pc = __ pc(); 3876 3877#if defined(ABI_ELFv2) 3878 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3879 __ call_c(entry, relocInfo::runtime_call_type); 3880#else 3881 // The function we're going to call. 3882 FunctionDescriptor fdtemp; 3883 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3884 3885 Register Rtoc = R12_scratch2; 3886 // Calculate the method's TOC. 3887 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3888 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3889 // pool entries; call_c_using_toc will optimize the call. 3890 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3891 if (!success) { 3892 ciEnv::current()->record_out_of_memory_failure(); 3893 return; 3894 } 3895#endif 3896 3897 // Check the ret_addr_offset. 3898 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3899 "Fix constant in ret_addr_offset()"); 3900 %} 3901 3902 // Move to ctr for leaf call. 3903 // This enc_class is needed so that scheduler gets proper 3904 // input mapping for latency computation. 3905 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3906 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3907 MacroAssembler _masm(&cbuf); 3908 __ mtctr($src$$Register); 3909 %} 3910 3911 // Postalloc expand emitter for runtime leaf calls. 3912 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3913 loadConLNodesTuple loadConLNodes_Entry; 3914#if defined(ABI_ELFv2) 3915 jlong entry_address = (jlong) this->entry_point(); 3916 assert(entry_address, "need address here"); 3917 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3918 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3919#else 3920 // Get the struct that describes the function we are about to call. 3921 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3922 assert(fd, "need fd here"); 3923 jlong entry_address = (jlong) fd->entry(); 3924 // new nodes 3925 loadConLNodesTuple loadConLNodes_Env; 3926 loadConLNodesTuple loadConLNodes_Toc; 3927 3928 // Create nodes and operands for loading the entry point. 3929 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3930 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3931 3932 3933 // Create nodes and operands for loading the env pointer. 3934 if (fd->env() != NULL) { 3935 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3936 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3937 } else { 3938 loadConLNodes_Env._large_hi = NULL; 3939 loadConLNodes_Env._large_lo = NULL; 3940 loadConLNodes_Env._small = NULL; 3941 loadConLNodes_Env._last = new loadConL16Node(); 3942 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3943 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3944 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3945 } 3946 3947 // Create nodes and operands for loading the Toc point. 3948 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3949 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3950#endif // ABI_ELFv2 3951 // mtctr node 3952 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3953 3954 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3955 mtctr->add_req(0, loadConLNodes_Entry._last); 3956 3957 mtctr->_opnds[0] = new iRegLdstOper(); 3958 mtctr->_opnds[1] = new iRegLdstOper(); 3959 3960 // call node 3961 MachCallLeafNode *call = new CallLeafDirectNode(); 3962 3963 call->_opnds[0] = _opnds[0]; 3964 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3965 3966 // Make the new call node look like the old one. 3967 call->_name = _name; 3968 call->_tf = _tf; 3969 call->_entry_point = _entry_point; 3970 call->_cnt = _cnt; 3971 call->_argsize = _argsize; 3972 call->_oop_map = _oop_map; 3973 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3974 call->_jvms = NULL; 3975 call->_jvmadj = _jvmadj; 3976 call->_in_rms = _in_rms; 3977 call->_nesting = _nesting; 3978 3979 3980 // New call needs all inputs of old call. 3981 // Req... 3982 for (uint i = 0; i < req(); ++i) { 3983 if (i != mach_constant_base_node_input()) { 3984 call->add_req(in(i)); 3985 } 3986 } 3987 3988 // These must be reqired edges, as the registers are live up to 3989 // the call. Else the constants are handled as kills. 3990 call->add_req(mtctr); 3991#if !defined(ABI_ELFv2) 3992 call->add_req(loadConLNodes_Env._last); 3993 call->add_req(loadConLNodes_Toc._last); 3994#endif 3995 3996 // ...as well as prec 3997 for (uint i = req(); i < len(); ++i) { 3998 call->add_prec(in(i)); 3999 } 4000 4001 // registers 4002 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 4003 4004 // Insert the new nodes. 4005 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 4006 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 4007#if !defined(ABI_ELFv2) 4008 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 4009 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 4010 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 4011 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 4012#endif 4013 nodes->push(mtctr); 4014 nodes->push(call); 4015 %} 4016%} 4017 4018//----------FRAME-------------------------------------------------------------- 4019// Definition of frame structure and management information. 4020 4021frame %{ 4022 // What direction does stack grow in (assumed to be same for native & Java). 4023 stack_direction(TOWARDS_LOW); 4024 4025 // These two registers define part of the calling convention between 4026 // compiled code and the interpreter. 4027 4028 // Inline Cache Register or method for I2C. 4029 inline_cache_reg(R19); // R19_method 4030 4031 // Method Oop Register when calling interpreter. 4032 interpreter_method_oop_reg(R19); // R19_method 4033 4034 // Optional: name the operand used by cisc-spilling to access 4035 // [stack_pointer + offset]. 4036 cisc_spilling_operand_name(indOffset); 4037 4038 // Number of stack slots consumed by a Monitor enter. 4039 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 4040 4041 // Compiled code's Frame Pointer. 4042 frame_pointer(R1); // R1_SP 4043 4044 // Interpreter stores its frame pointer in a register which is 4045 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 4046 // interpreted java to compiled java. 4047 // 4048 // R14_state holds pointer to caller's cInterpreter. 4049 interpreter_frame_pointer(R14); // R14_state 4050 4051 stack_alignment(frame::alignment_in_bytes); 4052 4053 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 4054 4055 // Number of outgoing stack slots killed above the 4056 // out_preserve_stack_slots for calls to C. Supports the var-args 4057 // backing area for register parms. 4058 // 4059 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 4060 4061 // The after-PROLOG location of the return address. Location of 4062 // return address specifies a type (REG or STACK) and a number 4063 // representing the register number (i.e. - use a register name) or 4064 // stack slot. 4065 // 4066 // A: Link register is stored in stack slot ... 4067 // M: ... but it's in the caller's frame according to PPC-64 ABI. 4068 // J: Therefore, we make sure that the link register is also in R11_scratch1 4069 // at the end of the prolog. 4070 // B: We use R20, now. 4071 //return_addr(REG R20); 4072 4073 // G: After reading the comments made by all the luminaries on their 4074 // failure to tell the compiler where the return address really is, 4075 // I hardly dare to try myself. However, I'm convinced it's in slot 4076 // 4 what apparently works and saves us some spills. 4077 return_addr(STACK 4); 4078 4079 // This is the body of the function 4080 // 4081 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 4082 // uint length, // length of array 4083 // bool is_outgoing) 4084 // 4085 // The `sig' array is to be updated. sig[j] represents the location 4086 // of the j-th argument, either a register or a stack slot. 4087 4088 // Comment taken from i486.ad: 4089 // Body of function which returns an integer array locating 4090 // arguments either in registers or in stack slots. Passed an array 4091 // of ideal registers called "sig" and a "length" count. Stack-slot 4092 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4093 // arguments for a CALLEE. Incoming stack arguments are 4094 // automatically biased by the preserve_stack_slots field above. 4095 calling_convention %{ 4096 // No difference between ingoing/outgoing. Just pass false. 4097 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4098 %} 4099 4100 // Comment taken from i486.ad: 4101 // Body of function which returns an integer array locating 4102 // arguments either in registers or in stack slots. Passed an array 4103 // of ideal registers called "sig" and a "length" count. Stack-slot 4104 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4105 // arguments for a CALLEE. Incoming stack arguments are 4106 // automatically biased by the preserve_stack_slots field above. 4107 c_calling_convention %{ 4108 // This is obviously always outgoing. 4109 // C argument in register AND stack slot. 4110 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 4111 %} 4112 4113 // Location of native (C/C++) and interpreter return values. This 4114 // is specified to be the same as Java. In the 32-bit VM, long 4115 // values are actually returned from native calls in O0:O1 and 4116 // returned to the interpreter in I0:I1. The copying to and from 4117 // the register pairs is done by the appropriate call and epilog 4118 // opcodes. This simplifies the register allocator. 4119 c_return_value %{ 4120 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4121 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4122 "only return normal values"); 4123 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4124 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4125 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4126 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4127 %} 4128 4129 // Location of compiled Java return values. Same as C 4130 return_value %{ 4131 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 4132 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 4133 "only return normal values"); 4134 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 4135 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 4136 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 4137 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 4138 %} 4139%} 4140 4141 4142//----------ATTRIBUTES--------------------------------------------------------- 4143 4144//----------Operand Attributes------------------------------------------------- 4145op_attrib op_cost(1); // Required cost attribute. 4146 4147//----------Instruction Attributes--------------------------------------------- 4148 4149// Cost attribute. required. 4150ins_attrib ins_cost(DEFAULT_COST); 4151 4152// Is this instruction a non-matching short branch variant of some 4153// long branch? Not required. 4154ins_attrib ins_short_branch(0); 4155 4156ins_attrib ins_is_TrapBasedCheckNode(true); 4157 4158// Number of constants. 4159// This instruction uses the given number of constants 4160// (optional attribute). 4161// This is needed to determine in time whether the constant pool will 4162// exceed 4000 entries. Before postalloc_expand the overall number of constants 4163// is determined. It's also used to compute the constant pool size 4164// in Output(). 4165ins_attrib ins_num_consts(0); 4166 4167// Required alignment attribute (must be a power of 2) specifies the 4168// alignment that some part of the instruction (not necessarily the 4169// start) requires. If > 1, a compute_padding() function must be 4170// provided for the instruction. 4171ins_attrib ins_alignment(1); 4172 4173// Enforce/prohibit rematerializations. 4174// - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 4175// then rematerialization of that instruction is prohibited and the 4176// instruction's value will be spilled if necessary. 4177// Causes that MachNode::rematerialize() returns false. 4178// - If an instruction is attributed with 'ins_should_rematerialize(true)' 4179// then rematerialization should be enforced and a copy of the instruction 4180// should be inserted if possible; rematerialization is not guaranteed. 4181// Note: this may result in rematerializations in front of every use. 4182// Causes that MachNode::rematerialize() can return true. 4183// (optional attribute) 4184ins_attrib ins_cannot_rematerialize(false); 4185ins_attrib ins_should_rematerialize(false); 4186 4187// Instruction has variable size depending on alignment. 4188ins_attrib ins_variable_size_depending_on_alignment(false); 4189 4190// Instruction is a nop. 4191ins_attrib ins_is_nop(false); 4192 4193// Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 4194ins_attrib ins_use_mach_if_fast_lock_node(false); 4195 4196// Field for the toc offset of a constant. 4197// 4198// This is needed if the toc offset is not encodable as an immediate in 4199// the PPC load instruction. If so, the upper (hi) bits of the offset are 4200// added to the toc, and from this a load with immediate is performed. 4201// With postalloc expand, we get two nodes that require the same offset 4202// but which don't know about each other. The offset is only known 4203// when the constant is added to the constant pool during emitting. 4204// It is generated in the 'hi'-node adding the upper bits, and saved 4205// in this node. The 'lo'-node has a link to the 'hi'-node and reads 4206// the offset from there when it gets encoded. 4207ins_attrib ins_field_const_toc_offset(0); 4208ins_attrib ins_field_const_toc_offset_hi_node(0); 4209 4210// A field that can hold the instructions offset in the code buffer. 4211// Set in the nodes emitter. 4212ins_attrib ins_field_cbuf_insts_offset(-1); 4213 4214// Fields for referencing a call's load-IC-node. 4215// If the toc offset can not be encoded as an immediate in a load, we 4216// use two nodes. 4217ins_attrib ins_field_load_ic_hi_node(0); 4218ins_attrib ins_field_load_ic_node(0); 4219 4220//----------OPERANDS----------------------------------------------------------- 4221// Operand definitions must precede instruction definitions for correct 4222// parsing in the ADLC because operands constitute user defined types 4223// which are used in instruction definitions. 4224// 4225// Formats are generated automatically for constants and base registers. 4226 4227operand vecX() %{ 4228 constraint(ALLOC_IN_RC(vs_reg)); 4229 match(VecX); 4230 4231 format %{ %} 4232 interface(REG_INTER); 4233%} 4234 4235//----------Simple Operands---------------------------------------------------- 4236// Immediate Operands 4237 4238// Integer Immediate: 32-bit 4239operand immI() %{ 4240 match(ConI); 4241 op_cost(40); 4242 format %{ %} 4243 interface(CONST_INTER); 4244%} 4245 4246operand immI8() %{ 4247 predicate(Assembler::is_simm(n->get_int(), 8)); 4248 op_cost(0); 4249 match(ConI); 4250 format %{ %} 4251 interface(CONST_INTER); 4252%} 4253 4254// Integer Immediate: 16-bit 4255operand immI16() %{ 4256 predicate(Assembler::is_simm(n->get_int(), 16)); 4257 op_cost(0); 4258 match(ConI); 4259 format %{ %} 4260 interface(CONST_INTER); 4261%} 4262 4263// Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 4264operand immIhi16() %{ 4265 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 4266 match(ConI); 4267 op_cost(0); 4268 format %{ %} 4269 interface(CONST_INTER); 4270%} 4271 4272operand immInegpow2() %{ 4273 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 4274 match(ConI); 4275 op_cost(0); 4276 format %{ %} 4277 interface(CONST_INTER); 4278%} 4279 4280operand immIpow2minus1() %{ 4281 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 4282 match(ConI); 4283 op_cost(0); 4284 format %{ %} 4285 interface(CONST_INTER); 4286%} 4287 4288operand immIpowerOf2() %{ 4289 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 4290 match(ConI); 4291 op_cost(0); 4292 format %{ %} 4293 interface(CONST_INTER); 4294%} 4295 4296// Unsigned Integer Immediate: the values 0-31 4297operand uimmI5() %{ 4298 predicate(Assembler::is_uimm(n->get_int(), 5)); 4299 match(ConI); 4300 op_cost(0); 4301 format %{ %} 4302 interface(CONST_INTER); 4303%} 4304 4305// Unsigned Integer Immediate: 6-bit 4306operand uimmI6() %{ 4307 predicate(Assembler::is_uimm(n->get_int(), 6)); 4308 match(ConI); 4309 op_cost(0); 4310 format %{ %} 4311 interface(CONST_INTER); 4312%} 4313 4314// Unsigned Integer Immediate: 6-bit int, greater than 32 4315operand uimmI6_ge32() %{ 4316 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 4317 match(ConI); 4318 op_cost(0); 4319 format %{ %} 4320 interface(CONST_INTER); 4321%} 4322 4323// Unsigned Integer Immediate: 15-bit 4324operand uimmI15() %{ 4325 predicate(Assembler::is_uimm(n->get_int(), 15)); 4326 match(ConI); 4327 op_cost(0); 4328 format %{ %} 4329 interface(CONST_INTER); 4330%} 4331 4332// Unsigned Integer Immediate: 16-bit 4333operand uimmI16() %{ 4334 predicate(Assembler::is_uimm(n->get_int(), 16)); 4335 match(ConI); 4336 op_cost(0); 4337 format %{ %} 4338 interface(CONST_INTER); 4339%} 4340 4341// constant 'int 0'. 4342operand immI_0() %{ 4343 predicate(n->get_int() == 0); 4344 match(ConI); 4345 op_cost(0); 4346 format %{ %} 4347 interface(CONST_INTER); 4348%} 4349 4350// constant 'int 1'. 4351operand immI_1() %{ 4352 predicate(n->get_int() == 1); 4353 match(ConI); 4354 op_cost(0); 4355 format %{ %} 4356 interface(CONST_INTER); 4357%} 4358 4359// constant 'int -1'. 4360operand immI_minus1() %{ 4361 predicate(n->get_int() == -1); 4362 match(ConI); 4363 op_cost(0); 4364 format %{ %} 4365 interface(CONST_INTER); 4366%} 4367 4368// int value 16. 4369operand immI_16() %{ 4370 predicate(n->get_int() == 16); 4371 match(ConI); 4372 op_cost(0); 4373 format %{ %} 4374 interface(CONST_INTER); 4375%} 4376 4377// int value 24. 4378operand immI_24() %{ 4379 predicate(n->get_int() == 24); 4380 match(ConI); 4381 op_cost(0); 4382 format %{ %} 4383 interface(CONST_INTER); 4384%} 4385 4386// Compressed oops constants 4387// Pointer Immediate 4388operand immN() %{ 4389 match(ConN); 4390 4391 op_cost(10); 4392 format %{ %} 4393 interface(CONST_INTER); 4394%} 4395 4396// NULL Pointer Immediate 4397operand immN_0() %{ 4398 predicate(n->get_narrowcon() == 0); 4399 match(ConN); 4400 4401 op_cost(0); 4402 format %{ %} 4403 interface(CONST_INTER); 4404%} 4405 4406// Compressed klass constants 4407operand immNKlass() %{ 4408 match(ConNKlass); 4409 4410 op_cost(0); 4411 format %{ %} 4412 interface(CONST_INTER); 4413%} 4414 4415// This operand can be used to avoid matching of an instruct 4416// with chain rule. 4417operand immNKlass_NM() %{ 4418 match(ConNKlass); 4419 predicate(false); 4420 op_cost(0); 4421 format %{ %} 4422 interface(CONST_INTER); 4423%} 4424 4425// Pointer Immediate: 64-bit 4426operand immP() %{ 4427 match(ConP); 4428 op_cost(0); 4429 format %{ %} 4430 interface(CONST_INTER); 4431%} 4432 4433// Operand to avoid match of loadConP. 4434// This operand can be used to avoid matching of an instruct 4435// with chain rule. 4436operand immP_NM() %{ 4437 match(ConP); 4438 predicate(false); 4439 op_cost(0); 4440 format %{ %} 4441 interface(CONST_INTER); 4442%} 4443 4444// costant 'pointer 0'. 4445operand immP_0() %{ 4446 predicate(n->get_ptr() == 0); 4447 match(ConP); 4448 op_cost(0); 4449 format %{ %} 4450 interface(CONST_INTER); 4451%} 4452 4453// pointer 0x0 or 0x1 4454operand immP_0or1() %{ 4455 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4456 match(ConP); 4457 op_cost(0); 4458 format %{ %} 4459 interface(CONST_INTER); 4460%} 4461 4462operand immL() %{ 4463 match(ConL); 4464 op_cost(40); 4465 format %{ %} 4466 interface(CONST_INTER); 4467%} 4468 4469operand immLmax30() %{ 4470 predicate((n->get_long() <= 30)); 4471 match(ConL); 4472 op_cost(0); 4473 format %{ %} 4474 interface(CONST_INTER); 4475%} 4476 4477// Long Immediate: 16-bit 4478operand immL16() %{ 4479 predicate(Assembler::is_simm(n->get_long(), 16)); 4480 match(ConL); 4481 op_cost(0); 4482 format %{ %} 4483 interface(CONST_INTER); 4484%} 4485 4486// Long Immediate: 16-bit, 4-aligned 4487operand immL16Alg4() %{ 4488 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4489 match(ConL); 4490 op_cost(0); 4491 format %{ %} 4492 interface(CONST_INTER); 4493%} 4494 4495// Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4496operand immL32hi16() %{ 4497 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4498 match(ConL); 4499 op_cost(0); 4500 format %{ %} 4501 interface(CONST_INTER); 4502%} 4503 4504// Long Immediate: 32-bit 4505operand immL32() %{ 4506 predicate(Assembler::is_simm(n->get_long(), 32)); 4507 match(ConL); 4508 op_cost(0); 4509 format %{ %} 4510 interface(CONST_INTER); 4511%} 4512 4513// Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4514operand immLhighest16() %{ 4515 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4516 match(ConL); 4517 op_cost(0); 4518 format %{ %} 4519 interface(CONST_INTER); 4520%} 4521 4522operand immLnegpow2() %{ 4523 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4524 match(ConL); 4525 op_cost(0); 4526 format %{ %} 4527 interface(CONST_INTER); 4528%} 4529 4530operand immLpow2minus1() %{ 4531 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4532 (n->get_long() != (jlong)0xffffffffffffffffL)); 4533 match(ConL); 4534 op_cost(0); 4535 format %{ %} 4536 interface(CONST_INTER); 4537%} 4538 4539// constant 'long 0'. 4540operand immL_0() %{ 4541 predicate(n->get_long() == 0L); 4542 match(ConL); 4543 op_cost(0); 4544 format %{ %} 4545 interface(CONST_INTER); 4546%} 4547 4548// constat ' long -1'. 4549operand immL_minus1() %{ 4550 predicate(n->get_long() == -1L); 4551 match(ConL); 4552 op_cost(0); 4553 format %{ %} 4554 interface(CONST_INTER); 4555%} 4556 4557// Long Immediate: low 32-bit mask 4558operand immL_32bits() %{ 4559 predicate(n->get_long() == 0xFFFFFFFFL); 4560 match(ConL); 4561 op_cost(0); 4562 format %{ %} 4563 interface(CONST_INTER); 4564%} 4565 4566// Unsigned Long Immediate: 16-bit 4567operand uimmL16() %{ 4568 predicate(Assembler::is_uimm(n->get_long(), 16)); 4569 match(ConL); 4570 op_cost(0); 4571 format %{ %} 4572 interface(CONST_INTER); 4573%} 4574 4575// Float Immediate 4576operand immF() %{ 4577 match(ConF); 4578 op_cost(40); 4579 format %{ %} 4580 interface(CONST_INTER); 4581%} 4582 4583// Float Immediate: +0.0f. 4584operand immF_0() %{ 4585 predicate(jint_cast(n->getf()) == 0); 4586 match(ConF); 4587 4588 op_cost(0); 4589 format %{ %} 4590 interface(CONST_INTER); 4591%} 4592 4593// Double Immediate 4594operand immD() %{ 4595 match(ConD); 4596 op_cost(40); 4597 format %{ %} 4598 interface(CONST_INTER); 4599%} 4600 4601// Double Immediate: +0.0d. 4602operand immD_0() %{ 4603 predicate(jlong_cast(n->getd()) == 0); 4604 match(ConD); 4605 4606 op_cost(0); 4607 format %{ %} 4608 interface(CONST_INTER); 4609%} 4610 4611// Integer Register Operands 4612// Integer Destination Register 4613// See definition of reg_class bits32_reg_rw. 4614operand iRegIdst() %{ 4615 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4616 match(RegI); 4617 match(rscratch1RegI); 4618 match(rscratch2RegI); 4619 match(rarg1RegI); 4620 match(rarg2RegI); 4621 match(rarg3RegI); 4622 match(rarg4RegI); 4623 format %{ %} 4624 interface(REG_INTER); 4625%} 4626 4627// Integer Source Register 4628// See definition of reg_class bits32_reg_ro. 4629operand iRegIsrc() %{ 4630 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4631 match(RegI); 4632 match(rscratch1RegI); 4633 match(rscratch2RegI); 4634 match(rarg1RegI); 4635 match(rarg2RegI); 4636 match(rarg3RegI); 4637 match(rarg4RegI); 4638 format %{ %} 4639 interface(REG_INTER); 4640%} 4641 4642operand rscratch1RegI() %{ 4643 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4644 match(iRegIdst); 4645 format %{ %} 4646 interface(REG_INTER); 4647%} 4648 4649operand rscratch2RegI() %{ 4650 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4651 match(iRegIdst); 4652 format %{ %} 4653 interface(REG_INTER); 4654%} 4655 4656operand rarg1RegI() %{ 4657 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4658 match(iRegIdst); 4659 format %{ %} 4660 interface(REG_INTER); 4661%} 4662 4663operand rarg2RegI() %{ 4664 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4665 match(iRegIdst); 4666 format %{ %} 4667 interface(REG_INTER); 4668%} 4669 4670operand rarg3RegI() %{ 4671 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4672 match(iRegIdst); 4673 format %{ %} 4674 interface(REG_INTER); 4675%} 4676 4677operand rarg4RegI() %{ 4678 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4679 match(iRegIdst); 4680 format %{ %} 4681 interface(REG_INTER); 4682%} 4683 4684operand rarg1RegL() %{ 4685 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4686 match(iRegLdst); 4687 format %{ %} 4688 interface(REG_INTER); 4689%} 4690 4691operand rarg2RegL() %{ 4692 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4693 match(iRegLdst); 4694 format %{ %} 4695 interface(REG_INTER); 4696%} 4697 4698operand rarg3RegL() %{ 4699 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4700 match(iRegLdst); 4701 format %{ %} 4702 interface(REG_INTER); 4703%} 4704 4705operand rarg4RegL() %{ 4706 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4707 match(iRegLdst); 4708 format %{ %} 4709 interface(REG_INTER); 4710%} 4711 4712// Pointer Destination Register 4713// See definition of reg_class bits64_reg_rw. 4714operand iRegPdst() %{ 4715 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4716 match(RegP); 4717 match(rscratch1RegP); 4718 match(rscratch2RegP); 4719 match(rarg1RegP); 4720 match(rarg2RegP); 4721 match(rarg3RegP); 4722 match(rarg4RegP); 4723 format %{ %} 4724 interface(REG_INTER); 4725%} 4726 4727// Pointer Destination Register 4728// Operand not using r11 and r12 (killed in epilog). 4729operand iRegPdstNoScratch() %{ 4730 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4731 match(RegP); 4732 match(rarg1RegP); 4733 match(rarg2RegP); 4734 match(rarg3RegP); 4735 match(rarg4RegP); 4736 format %{ %} 4737 interface(REG_INTER); 4738%} 4739 4740// Pointer Source Register 4741// See definition of reg_class bits64_reg_ro. 4742operand iRegPsrc() %{ 4743 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4744 match(RegP); 4745 match(iRegPdst); 4746 match(rscratch1RegP); 4747 match(rscratch2RegP); 4748 match(rarg1RegP); 4749 match(rarg2RegP); 4750 match(rarg3RegP); 4751 match(rarg4RegP); 4752 match(threadRegP); 4753 format %{ %} 4754 interface(REG_INTER); 4755%} 4756 4757// Thread operand. 4758operand threadRegP() %{ 4759 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4760 match(iRegPdst); 4761 format %{ "R16" %} 4762 interface(REG_INTER); 4763%} 4764 4765operand rscratch1RegP() %{ 4766 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4767 match(iRegPdst); 4768 format %{ "R11" %} 4769 interface(REG_INTER); 4770%} 4771 4772operand rscratch2RegP() %{ 4773 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4774 match(iRegPdst); 4775 format %{ %} 4776 interface(REG_INTER); 4777%} 4778 4779operand rarg1RegP() %{ 4780 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4781 match(iRegPdst); 4782 format %{ %} 4783 interface(REG_INTER); 4784%} 4785 4786operand rarg2RegP() %{ 4787 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4788 match(iRegPdst); 4789 format %{ %} 4790 interface(REG_INTER); 4791%} 4792 4793operand rarg3RegP() %{ 4794 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4795 match(iRegPdst); 4796 format %{ %} 4797 interface(REG_INTER); 4798%} 4799 4800operand rarg4RegP() %{ 4801 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4802 match(iRegPdst); 4803 format %{ %} 4804 interface(REG_INTER); 4805%} 4806 4807operand iRegNsrc() %{ 4808 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4809 match(RegN); 4810 match(iRegNdst); 4811 4812 format %{ %} 4813 interface(REG_INTER); 4814%} 4815 4816operand iRegNdst() %{ 4817 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4818 match(RegN); 4819 4820 format %{ %} 4821 interface(REG_INTER); 4822%} 4823 4824// Long Destination Register 4825// See definition of reg_class bits64_reg_rw. 4826operand iRegLdst() %{ 4827 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4828 match(RegL); 4829 match(rscratch1RegL); 4830 match(rscratch2RegL); 4831 format %{ %} 4832 interface(REG_INTER); 4833%} 4834 4835// Long Source Register 4836// See definition of reg_class bits64_reg_ro. 4837operand iRegLsrc() %{ 4838 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4839 match(RegL); 4840 match(iRegLdst); 4841 match(rscratch1RegL); 4842 match(rscratch2RegL); 4843 format %{ %} 4844 interface(REG_INTER); 4845%} 4846 4847// Special operand for ConvL2I. 4848operand iRegL2Isrc(iRegLsrc reg) %{ 4849 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4850 match(ConvL2I reg); 4851 format %{ "ConvL2I($reg)" %} 4852 interface(REG_INTER) 4853%} 4854 4855operand rscratch1RegL() %{ 4856 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4857 match(RegL); 4858 format %{ %} 4859 interface(REG_INTER); 4860%} 4861 4862operand rscratch2RegL() %{ 4863 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4864 match(RegL); 4865 format %{ %} 4866 interface(REG_INTER); 4867%} 4868 4869// Condition Code Flag Registers 4870operand flagsReg() %{ 4871 constraint(ALLOC_IN_RC(int_flags)); 4872 match(RegFlags); 4873 format %{ %} 4874 interface(REG_INTER); 4875%} 4876 4877operand flagsRegSrc() %{ 4878 constraint(ALLOC_IN_RC(int_flags_ro)); 4879 match(RegFlags); 4880 match(flagsReg); 4881 match(flagsRegCR0); 4882 format %{ %} 4883 interface(REG_INTER); 4884%} 4885 4886// Condition Code Flag Register CR0 4887operand flagsRegCR0() %{ 4888 constraint(ALLOC_IN_RC(int_flags_CR0)); 4889 match(RegFlags); 4890 format %{ "CR0" %} 4891 interface(REG_INTER); 4892%} 4893 4894operand flagsRegCR1() %{ 4895 constraint(ALLOC_IN_RC(int_flags_CR1)); 4896 match(RegFlags); 4897 format %{ "CR1" %} 4898 interface(REG_INTER); 4899%} 4900 4901operand flagsRegCR6() %{ 4902 constraint(ALLOC_IN_RC(int_flags_CR6)); 4903 match(RegFlags); 4904 format %{ "CR6" %} 4905 interface(REG_INTER); 4906%} 4907 4908operand regCTR() %{ 4909 constraint(ALLOC_IN_RC(ctr_reg)); 4910 // RegFlags should work. Introducing a RegSpecial type would cause a 4911 // lot of changes. 4912 match(RegFlags); 4913 format %{"SR_CTR" %} 4914 interface(REG_INTER); 4915%} 4916 4917operand regD() %{ 4918 constraint(ALLOC_IN_RC(dbl_reg)); 4919 match(RegD); 4920 format %{ %} 4921 interface(REG_INTER); 4922%} 4923 4924operand regF() %{ 4925 constraint(ALLOC_IN_RC(flt_reg)); 4926 match(RegF); 4927 format %{ %} 4928 interface(REG_INTER); 4929%} 4930 4931// Special Registers 4932 4933// Method Register 4934operand inline_cache_regP(iRegPdst reg) %{ 4935 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4936 match(reg); 4937 format %{ %} 4938 interface(REG_INTER); 4939%} 4940 4941operand compiler_method_oop_regP(iRegPdst reg) %{ 4942 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4943 match(reg); 4944 format %{ %} 4945 interface(REG_INTER); 4946%} 4947 4948operand interpreter_method_oop_regP(iRegPdst reg) %{ 4949 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4950 match(reg); 4951 format %{ %} 4952 interface(REG_INTER); 4953%} 4954 4955// Operands to remove register moves in unscaled mode. 4956// Match read/write registers with an EncodeP node if neither shift nor add are required. 4957operand iRegP2N(iRegPsrc reg) %{ 4958 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4959 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4960 match(EncodeP reg); 4961 format %{ "$reg" %} 4962 interface(REG_INTER) 4963%} 4964 4965operand iRegN2P(iRegNsrc reg) %{ 4966 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4967 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4968 match(DecodeN reg); 4969 format %{ "$reg" %} 4970 interface(REG_INTER) 4971%} 4972 4973operand iRegN2P_klass(iRegNsrc reg) %{ 4974 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4975 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4976 match(DecodeNKlass reg); 4977 format %{ "$reg" %} 4978 interface(REG_INTER) 4979%} 4980 4981//----------Complex Operands--------------------------------------------------- 4982// Indirect Memory Reference 4983operand indirect(iRegPsrc reg) %{ 4984 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4985 match(reg); 4986 op_cost(100); 4987 format %{ "[$reg]" %} 4988 interface(MEMORY_INTER) %{ 4989 base($reg); 4990 index(0x0); 4991 scale(0x0); 4992 disp(0x0); 4993 %} 4994%} 4995 4996// Indirect with Offset 4997operand indOffset16(iRegPsrc reg, immL16 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// Indirect with 4-aligned Offset 5011operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 5012 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5013 match(AddP reg offset); 5014 op_cost(100); 5015 format %{ "[$reg + $offset]" %} 5016 interface(MEMORY_INTER) %{ 5017 base($reg); 5018 index(0x0); 5019 scale(0x0); 5020 disp($offset); 5021 %} 5022%} 5023 5024//----------Complex Operands for Compressed OOPs------------------------------- 5025// Compressed OOPs with narrow_oop_shift == 0. 5026 5027// Indirect Memory Reference, compressed OOP 5028operand indirectNarrow(iRegNsrc reg) %{ 5029 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5030 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5031 match(DecodeN 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 5042operand indirectNarrow_klass(iRegNsrc reg) %{ 5043 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5044 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5045 match(DecodeNKlass reg); 5046 op_cost(100); 5047 format %{ "[$reg]" %} 5048 interface(MEMORY_INTER) %{ 5049 base($reg); 5050 index(0x0); 5051 scale(0x0); 5052 disp(0x0); 5053 %} 5054%} 5055 5056// Indirect with Offset, compressed OOP 5057operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 5058 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5059 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5060 match(AddP (DecodeN 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 5071operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 5072 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5073 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5074 match(AddP (DecodeNKlass reg) offset); 5075 op_cost(100); 5076 format %{ "[$reg + $offset]" %} 5077 interface(MEMORY_INTER) %{ 5078 base($reg); 5079 index(0x0); 5080 scale(0x0); 5081 disp($offset); 5082 %} 5083%} 5084 5085// Indirect with 4-aligned Offset, compressed OOP 5086operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 5087 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 5088 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5089 match(AddP (DecodeN 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 5100operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 5101 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 5102 constraint(ALLOC_IN_RC(bits64_reg_ro)); 5103 match(AddP (DecodeNKlass reg) offset); 5104 op_cost(100); 5105 format %{ "[$reg + $offset]" %} 5106 interface(MEMORY_INTER) %{ 5107 base($reg); 5108 index(0x0); 5109 scale(0x0); 5110 disp($offset); 5111 %} 5112%} 5113 5114//----------Special Memory Operands-------------------------------------------- 5115// Stack Slot Operand 5116// 5117// This operand is used for loading and storing temporary values on 5118// the stack where a match requires a value to flow through memory. 5119operand stackSlotI(sRegI reg) %{ 5120 constraint(ALLOC_IN_RC(stack_slots)); 5121 op_cost(100); 5122 //match(RegI); 5123 format %{ "[sp+$reg]" %} 5124 interface(MEMORY_INTER) %{ 5125 base(0x1); // R1_SP 5126 index(0x0); 5127 scale(0x0); 5128 disp($reg); // Stack Offset 5129 %} 5130%} 5131 5132operand stackSlotL(sRegL reg) %{ 5133 constraint(ALLOC_IN_RC(stack_slots)); 5134 op_cost(100); 5135 //match(RegL); 5136 format %{ "[sp+$reg]" %} 5137 interface(MEMORY_INTER) %{ 5138 base(0x1); // R1_SP 5139 index(0x0); 5140 scale(0x0); 5141 disp($reg); // Stack Offset 5142 %} 5143%} 5144 5145operand stackSlotP(sRegP reg) %{ 5146 constraint(ALLOC_IN_RC(stack_slots)); 5147 op_cost(100); 5148 //match(RegP); 5149 format %{ "[sp+$reg]" %} 5150 interface(MEMORY_INTER) %{ 5151 base(0x1); // R1_SP 5152 index(0x0); 5153 scale(0x0); 5154 disp($reg); // Stack Offset 5155 %} 5156%} 5157 5158operand stackSlotF(sRegF reg) %{ 5159 constraint(ALLOC_IN_RC(stack_slots)); 5160 op_cost(100); 5161 //match(RegF); 5162 format %{ "[sp+$reg]" %} 5163 interface(MEMORY_INTER) %{ 5164 base(0x1); // R1_SP 5165 index(0x0); 5166 scale(0x0); 5167 disp($reg); // Stack Offset 5168 %} 5169%} 5170 5171operand stackSlotD(sRegD reg) %{ 5172 constraint(ALLOC_IN_RC(stack_slots)); 5173 op_cost(100); 5174 //match(RegD); 5175 format %{ "[sp+$reg]" %} 5176 interface(MEMORY_INTER) %{ 5177 base(0x1); // R1_SP 5178 index(0x0); 5179 scale(0x0); 5180 disp($reg); // Stack Offset 5181 %} 5182%} 5183 5184// Operands for expressing Control Flow 5185// NOTE: Label is a predefined operand which should not be redefined in 5186// the AD file. It is generically handled within the ADLC. 5187 5188//----------Conditional Branch Operands---------------------------------------- 5189// Comparison Op 5190// 5191// This is the operation of the comparison, and is limited to the 5192// following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 5193// (!=). 5194// 5195// Other attributes of the comparison, such as unsignedness, are specified 5196// by the comparison instruction that sets a condition code flags register. 5197// That result is represented by a flags operand whose subtype is appropriate 5198// to the unsignedness (etc.) of the comparison. 5199// 5200// Later, the instruction which matches both the Comparison Op (a Bool) and 5201// the flags (produced by the Cmp) specifies the coding of the comparison op 5202// by matching a specific subtype of Bool operand below. 5203 5204// When used for floating point comparisons: unordered same as less. 5205operand cmpOp() %{ 5206 match(Bool); 5207 format %{ "" %} 5208 interface(COND_INTER) %{ 5209 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 5210 // BO & BI 5211 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 5212 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 5213 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 5214 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 5215 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 5216 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 5217 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 5218 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 5219 %} 5220%} 5221 5222//----------OPERAND CLASSES---------------------------------------------------- 5223// Operand Classes are groups of operands that are used to simplify 5224// instruction definitions by not requiring the AD writer to specify 5225// seperate instructions for every form of operand when the 5226// instruction accepts multiple operand types with the same basic 5227// encoding and format. The classic case of this is memory operands. 5228// Indirect is not included since its use is limited to Compare & Swap. 5229 5230opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 5231// Memory operand where offsets are 4-aligned. Required for ld, std. 5232opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 5233opclass indirectMemory(indirect, indirectNarrow); 5234 5235// Special opclass for I and ConvL2I. 5236opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 5237 5238// Operand classes to match encode and decode. iRegN_P2N is only used 5239// for storeN. I have never seen an encode node elsewhere. 5240opclass iRegN_P2N(iRegNsrc, iRegP2N); 5241opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 5242 5243//----------PIPELINE----------------------------------------------------------- 5244 5245pipeline %{ 5246 5247// See J.M.Tendler et al. "Power4 system microarchitecture", IBM 5248// J. Res. & Dev., No. 1, Jan. 2002. 5249 5250//----------ATTRIBUTES--------------------------------------------------------- 5251attributes %{ 5252 5253 // Power4 instructions are of fixed length. 5254 fixed_size_instructions; 5255 5256 // TODO: if `bundle' means number of instructions fetched 5257 // per cycle, this is 8. If `bundle' means Power4 `group', that is 5258 // max instructions issued per cycle, this is 5. 5259 max_instructions_per_bundle = 8; 5260 5261 // A Power4 instruction is 4 bytes long. 5262 instruction_unit_size = 4; 5263 5264 // The Power4 processor fetches 64 bytes... 5265 instruction_fetch_unit_size = 64; 5266 5267 // ...in one line 5268 instruction_fetch_units = 1 5269 5270 // Unused, list one so that array generated by adlc is not empty. 5271 // Aix compiler chokes if _nop_count = 0. 5272 nops(fxNop); 5273%} 5274 5275//----------RESOURCES---------------------------------------------------------- 5276// Resources are the functional units available to the machine 5277resources( 5278 PPC_BR, // branch unit 5279 PPC_CR, // condition unit 5280 PPC_FX1, // integer arithmetic unit 1 5281 PPC_FX2, // integer arithmetic unit 2 5282 PPC_LDST1, // load/store unit 1 5283 PPC_LDST2, // load/store unit 2 5284 PPC_FP1, // float arithmetic unit 1 5285 PPC_FP2, // float arithmetic unit 2 5286 PPC_LDST = PPC_LDST1 | PPC_LDST2, 5287 PPC_FX = PPC_FX1 | PPC_FX2, 5288 PPC_FP = PPC_FP1 | PPC_FP2 5289 ); 5290 5291//----------PIPELINE DESCRIPTION----------------------------------------------- 5292// Pipeline Description specifies the stages in the machine's pipeline 5293pipe_desc( 5294 // Power4 longest pipeline path 5295 PPC_IF, // instruction fetch 5296 PPC_IC, 5297 //PPC_BP, // branch prediction 5298 PPC_D0, // decode 5299 PPC_D1, // decode 5300 PPC_D2, // decode 5301 PPC_D3, // decode 5302 PPC_Xfer1, 5303 PPC_GD, // group definition 5304 PPC_MP, // map 5305 PPC_ISS, // issue 5306 PPC_RF, // resource fetch 5307 PPC_EX1, // execute (all units) 5308 PPC_EX2, // execute (FP, LDST) 5309 PPC_EX3, // execute (FP, LDST) 5310 PPC_EX4, // execute (FP) 5311 PPC_EX5, // execute (FP) 5312 PPC_EX6, // execute (FP) 5313 PPC_WB, // write back 5314 PPC_Xfer2, 5315 PPC_CP 5316 ); 5317 5318//----------PIPELINE CLASSES--------------------------------------------------- 5319// Pipeline Classes describe the stages in which input and output are 5320// referenced by the hardware pipeline. 5321 5322// Simple pipeline classes. 5323 5324// Default pipeline class. 5325pipe_class pipe_class_default() %{ 5326 single_instruction; 5327 fixed_latency(2); 5328%} 5329 5330// Pipeline class for empty instructions. 5331pipe_class pipe_class_empty() %{ 5332 single_instruction; 5333 fixed_latency(0); 5334%} 5335 5336// Pipeline class for compares. 5337pipe_class pipe_class_compare() %{ 5338 single_instruction; 5339 fixed_latency(16); 5340%} 5341 5342// Pipeline class for traps. 5343pipe_class pipe_class_trap() %{ 5344 single_instruction; 5345 fixed_latency(100); 5346%} 5347 5348// Pipeline class for memory operations. 5349pipe_class pipe_class_memory() %{ 5350 single_instruction; 5351 fixed_latency(16); 5352%} 5353 5354// Pipeline class for call. 5355pipe_class pipe_class_call() %{ 5356 single_instruction; 5357 fixed_latency(100); 5358%} 5359 5360// Define the class for the Nop node. 5361define %{ 5362 MachNop = pipe_class_default; 5363%} 5364 5365%} 5366 5367//----------INSTRUCTIONS------------------------------------------------------- 5368 5369// Naming of instructions: 5370// opA_operB / opA_operB_operC: 5371// Operation 'op' with one or two source operands 'oper'. Result 5372// type is A, source operand types are B and C. 5373// Iff A == B == C, B and C are left out. 5374// 5375// The instructions are ordered according to the following scheme: 5376// - loads 5377// - load constants 5378// - prefetch 5379// - store 5380// - encode/decode 5381// - membar 5382// - conditional moves 5383// - compare & swap 5384// - arithmetic and logic operations 5385// * int: Add, Sub, Mul, Div, Mod 5386// * int: lShift, arShift, urShift, rot 5387// * float: Add, Sub, Mul, Div 5388// * and, or, xor ... 5389// - register moves: float <-> int, reg <-> stack, repl 5390// - cast (high level type cast, XtoP, castPP, castII, not_null etc. 5391// - conv (low level type cast requiring bit changes (sign extend etc) 5392// - compares, range & zero checks. 5393// - branches 5394// - complex operations, intrinsics, min, max, replicate 5395// - lock 5396// - Calls 5397// 5398// If there are similar instructions with different types they are sorted: 5399// int before float 5400// small before big 5401// signed before unsigned 5402// e.g., loadS before loadUS before loadI before loadF. 5403 5404 5405//----------Load/Store Instructions-------------------------------------------- 5406 5407//----------Load Instructions-------------------------------------------------- 5408 5409// Converts byte to int. 5410// As convB2I_reg, but without match rule. The match rule of convB2I_reg 5411// reuses the 'amount' operand, but adlc expects that operand specification 5412// and operands in match rule are equivalent. 5413instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5414 effect(DEF dst, USE src); 5415 format %{ "EXTSB $dst, $src \t// byte->int" %} 5416 size(4); 5417 ins_encode %{ 5418 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5419 __ extsb($dst$$Register, $src$$Register); 5420 %} 5421 ins_pipe(pipe_class_default); 5422%} 5423 5424instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5425 // match-rule, false predicate 5426 match(Set dst (LoadB mem)); 5427 predicate(false); 5428 5429 format %{ "LBZ $dst, $mem" %} 5430 size(4); 5431 ins_encode( enc_lbz(dst, mem) ); 5432 ins_pipe(pipe_class_memory); 5433%} 5434 5435instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5436 // match-rule, false predicate 5437 match(Set dst (LoadB mem)); 5438 predicate(false); 5439 5440 format %{ "LBZ $dst, $mem\n\t" 5441 "TWI $dst\n\t" 5442 "ISYNC" %} 5443 size(12); 5444 ins_encode( enc_lbz_ac(dst, mem) ); 5445 ins_pipe(pipe_class_memory); 5446%} 5447 5448// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5449instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5450 match(Set dst (LoadB mem)); 5451 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5452 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5453 expand %{ 5454 iRegIdst tmp; 5455 loadUB_indirect(tmp, mem); 5456 convB2I_reg_2(dst, tmp); 5457 %} 5458%} 5459 5460instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5461 match(Set dst (LoadB mem)); 5462 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5463 expand %{ 5464 iRegIdst tmp; 5465 loadUB_indirect_ac(tmp, mem); 5466 convB2I_reg_2(dst, tmp); 5467 %} 5468%} 5469 5470instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5471 // match-rule, false predicate 5472 match(Set dst (LoadB mem)); 5473 predicate(false); 5474 5475 format %{ "LBZ $dst, $mem" %} 5476 size(4); 5477 ins_encode( enc_lbz(dst, mem) ); 5478 ins_pipe(pipe_class_memory); 5479%} 5480 5481instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5482 // match-rule, false predicate 5483 match(Set dst (LoadB mem)); 5484 predicate(false); 5485 5486 format %{ "LBZ $dst, $mem\n\t" 5487 "TWI $dst\n\t" 5488 "ISYNC" %} 5489 size(12); 5490 ins_encode( enc_lbz_ac(dst, mem) ); 5491 ins_pipe(pipe_class_memory); 5492%} 5493 5494// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5495instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5496 match(Set dst (LoadB mem)); 5497 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5498 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5499 5500 expand %{ 5501 iRegIdst tmp; 5502 loadUB_indOffset16(tmp, mem); 5503 convB2I_reg_2(dst, tmp); 5504 %} 5505%} 5506 5507instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5508 match(Set dst (LoadB mem)); 5509 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5510 5511 expand %{ 5512 iRegIdst tmp; 5513 loadUB_indOffset16_ac(tmp, mem); 5514 convB2I_reg_2(dst, tmp); 5515 %} 5516%} 5517 5518// Load Unsigned Byte (8bit UNsigned) into an int reg. 5519instruct loadUB(iRegIdst dst, memory mem) %{ 5520 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5521 match(Set dst (LoadUB mem)); 5522 ins_cost(MEMORY_REF_COST); 5523 5524 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5525 size(4); 5526 ins_encode( enc_lbz(dst, mem) ); 5527 ins_pipe(pipe_class_memory); 5528%} 5529 5530// Load Unsigned Byte (8bit UNsigned) acquire. 5531instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5532 match(Set dst (LoadUB mem)); 5533 ins_cost(3*MEMORY_REF_COST); 5534 5535 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5536 "TWI $dst\n\t" 5537 "ISYNC" %} 5538 size(12); 5539 ins_encode( enc_lbz_ac(dst, mem) ); 5540 ins_pipe(pipe_class_memory); 5541%} 5542 5543// Load Unsigned Byte (8bit UNsigned) into a Long Register. 5544instruct loadUB2L(iRegLdst dst, memory mem) %{ 5545 match(Set dst (ConvI2L (LoadUB mem))); 5546 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5547 ins_cost(MEMORY_REF_COST); 5548 5549 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5550 size(4); 5551 ins_encode( enc_lbz(dst, mem) ); 5552 ins_pipe(pipe_class_memory); 5553%} 5554 5555instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5556 match(Set dst (ConvI2L (LoadUB mem))); 5557 ins_cost(3*MEMORY_REF_COST); 5558 5559 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5560 "TWI $dst\n\t" 5561 "ISYNC" %} 5562 size(12); 5563 ins_encode( enc_lbz_ac(dst, mem) ); 5564 ins_pipe(pipe_class_memory); 5565%} 5566 5567// Load Short (16bit signed) 5568instruct loadS(iRegIdst dst, memory mem) %{ 5569 match(Set dst (LoadS mem)); 5570 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5571 ins_cost(MEMORY_REF_COST); 5572 5573 format %{ "LHA $dst, $mem" %} 5574 size(4); 5575 ins_encode %{ 5576 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5577 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5578 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5579 %} 5580 ins_pipe(pipe_class_memory); 5581%} 5582 5583// Load Short (16bit signed) acquire. 5584instruct loadS_ac(iRegIdst dst, memory mem) %{ 5585 match(Set dst (LoadS mem)); 5586 ins_cost(3*MEMORY_REF_COST); 5587 5588 format %{ "LHA $dst, $mem\t acquire\n\t" 5589 "TWI $dst\n\t" 5590 "ISYNC" %} 5591 size(12); 5592 ins_encode %{ 5593 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5594 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5595 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5596 __ twi_0($dst$$Register); 5597 __ isync(); 5598 %} 5599 ins_pipe(pipe_class_memory); 5600%} 5601 5602// Load Char (16bit unsigned) 5603instruct loadUS(iRegIdst dst, memory mem) %{ 5604 match(Set dst (LoadUS mem)); 5605 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5606 ins_cost(MEMORY_REF_COST); 5607 5608 format %{ "LHZ $dst, $mem" %} 5609 size(4); 5610 ins_encode( enc_lhz(dst, mem) ); 5611 ins_pipe(pipe_class_memory); 5612%} 5613 5614// Load Char (16bit unsigned) acquire. 5615instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5616 match(Set dst (LoadUS mem)); 5617 ins_cost(3*MEMORY_REF_COST); 5618 5619 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5620 "TWI $dst\n\t" 5621 "ISYNC" %} 5622 size(12); 5623 ins_encode( enc_lhz_ac(dst, mem) ); 5624 ins_pipe(pipe_class_memory); 5625%} 5626 5627// Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5628instruct loadUS2L(iRegLdst dst, memory mem) %{ 5629 match(Set dst (ConvI2L (LoadUS mem))); 5630 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5631 ins_cost(MEMORY_REF_COST); 5632 5633 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5634 size(4); 5635 ins_encode( enc_lhz(dst, mem) ); 5636 ins_pipe(pipe_class_memory); 5637%} 5638 5639// Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5640instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5641 match(Set dst (ConvI2L (LoadUS mem))); 5642 ins_cost(3*MEMORY_REF_COST); 5643 5644 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5645 "TWI $dst\n\t" 5646 "ISYNC" %} 5647 size(12); 5648 ins_encode( enc_lhz_ac(dst, mem) ); 5649 ins_pipe(pipe_class_memory); 5650%} 5651 5652// Load Integer. 5653instruct loadI(iRegIdst dst, memory mem) %{ 5654 match(Set dst (LoadI mem)); 5655 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5656 ins_cost(MEMORY_REF_COST); 5657 5658 format %{ "LWZ $dst, $mem" %} 5659 size(4); 5660 ins_encode( enc_lwz(dst, mem) ); 5661 ins_pipe(pipe_class_memory); 5662%} 5663 5664// Load Integer acquire. 5665instruct loadI_ac(iRegIdst dst, memory mem) %{ 5666 match(Set dst (LoadI mem)); 5667 ins_cost(3*MEMORY_REF_COST); 5668 5669 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5670 "TWI $dst\n\t" 5671 "ISYNC" %} 5672 size(12); 5673 ins_encode( enc_lwz_ac(dst, mem) ); 5674 ins_pipe(pipe_class_memory); 5675%} 5676 5677// Match loading integer and casting it to unsigned int in 5678// long register. 5679// LoadI + ConvI2L + AndL 0xffffffff. 5680instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5681 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5682 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5683 ins_cost(MEMORY_REF_COST); 5684 5685 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5686 size(4); 5687 ins_encode( enc_lwz(dst, mem) ); 5688 ins_pipe(pipe_class_memory); 5689%} 5690 5691// Match loading integer and casting it to long. 5692instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5693 match(Set dst (ConvI2L (LoadI mem))); 5694 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5695 ins_cost(MEMORY_REF_COST); 5696 5697 format %{ "LWA $dst, $mem \t// loadI2L" %} 5698 size(4); 5699 ins_encode %{ 5700 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5701 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5702 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5703 %} 5704 ins_pipe(pipe_class_memory); 5705%} 5706 5707// Match loading integer and casting it to long - acquire. 5708instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5709 match(Set dst (ConvI2L (LoadI mem))); 5710 ins_cost(3*MEMORY_REF_COST); 5711 5712 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5713 "TWI $dst\n\t" 5714 "ISYNC" %} 5715 size(12); 5716 ins_encode %{ 5717 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5718 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5719 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5720 __ twi_0($dst$$Register); 5721 __ isync(); 5722 %} 5723 ins_pipe(pipe_class_memory); 5724%} 5725 5726// Load Long - aligned 5727instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5728 match(Set dst (LoadL mem)); 5729 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5730 ins_cost(MEMORY_REF_COST); 5731 5732 format %{ "LD $dst, $mem \t// long" %} 5733 size(4); 5734 ins_encode( enc_ld(dst, mem) ); 5735 ins_pipe(pipe_class_memory); 5736%} 5737 5738// Load Long - aligned acquire. 5739instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5740 match(Set dst (LoadL mem)); 5741 ins_cost(3*MEMORY_REF_COST); 5742 5743 format %{ "LD $dst, $mem \t// long acquire\n\t" 5744 "TWI $dst\n\t" 5745 "ISYNC" %} 5746 size(12); 5747 ins_encode( enc_ld_ac(dst, mem) ); 5748 ins_pipe(pipe_class_memory); 5749%} 5750 5751// Load Long - UNaligned 5752instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5753 match(Set dst (LoadL_unaligned mem)); 5754 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5755 ins_cost(MEMORY_REF_COST); 5756 5757 format %{ "LD $dst, $mem \t// unaligned long" %} 5758 size(4); 5759 ins_encode( enc_ld(dst, mem) ); 5760 ins_pipe(pipe_class_memory); 5761%} 5762 5763// Load nodes for superwords 5764 5765// Load Aligned Packed Byte 5766instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5767 predicate(n->as_LoadVector()->memory_size() == 8); 5768 match(Set dst (LoadVector mem)); 5769 ins_cost(MEMORY_REF_COST); 5770 5771 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5772 size(4); 5773 ins_encode( enc_ld(dst, mem) ); 5774 ins_pipe(pipe_class_memory); 5775%} 5776 5777// Load Aligned Packed Byte 5778instruct loadV16(vecX dst, indirect mem) %{ 5779 predicate(n->as_LoadVector()->memory_size() == 16); 5780 match(Set dst (LoadVector mem)); 5781 ins_cost(MEMORY_REF_COST); 5782 5783 format %{ "LXVD2X $dst, $mem \t// load 16-byte Vector" %} 5784 size(4); 5785 ins_encode %{ 5786 __ lxvd2x($dst$$VectorSRegister, $mem$$Register); 5787 %} 5788 ins_pipe(pipe_class_default); 5789%} 5790 5791// Load Range, range = array length (=jint) 5792instruct loadRange(iRegIdst dst, memory mem) %{ 5793 match(Set dst (LoadRange mem)); 5794 ins_cost(MEMORY_REF_COST); 5795 5796 format %{ "LWZ $dst, $mem \t// range" %} 5797 size(4); 5798 ins_encode( enc_lwz(dst, mem) ); 5799 ins_pipe(pipe_class_memory); 5800%} 5801 5802// Load Compressed Pointer 5803instruct loadN(iRegNdst dst, memory mem) %{ 5804 match(Set dst (LoadN mem)); 5805 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5806 ins_cost(MEMORY_REF_COST); 5807 5808 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5809 size(4); 5810 ins_encode( enc_lwz(dst, mem) ); 5811 ins_pipe(pipe_class_memory); 5812%} 5813 5814// Load Compressed Pointer acquire. 5815instruct loadN_ac(iRegNdst dst, memory mem) %{ 5816 match(Set dst (LoadN mem)); 5817 ins_cost(3*MEMORY_REF_COST); 5818 5819 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5820 "TWI $dst\n\t" 5821 "ISYNC" %} 5822 size(12); 5823 ins_encode( enc_lwz_ac(dst, mem) ); 5824 ins_pipe(pipe_class_memory); 5825%} 5826 5827// Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5828instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5829 match(Set dst (DecodeN (LoadN mem))); 5830 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5831 ins_cost(MEMORY_REF_COST); 5832 5833 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5834 size(4); 5835 ins_encode( enc_lwz(dst, mem) ); 5836 ins_pipe(pipe_class_memory); 5837%} 5838 5839instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5840 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5841 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5842 _kids[0]->_leaf->as_Load()->is_unordered()); 5843 ins_cost(MEMORY_REF_COST); 5844 5845 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5846 size(4); 5847 ins_encode( enc_lwz(dst, mem) ); 5848 ins_pipe(pipe_class_memory); 5849%} 5850 5851// Load Pointer 5852instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5853 match(Set dst (LoadP mem)); 5854 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5855 ins_cost(MEMORY_REF_COST); 5856 5857 format %{ "LD $dst, $mem \t// ptr" %} 5858 size(4); 5859 ins_encode( enc_ld(dst, mem) ); 5860 ins_pipe(pipe_class_memory); 5861%} 5862 5863// Load Pointer acquire. 5864instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5865 match(Set dst (LoadP mem)); 5866 ins_cost(3*MEMORY_REF_COST); 5867 5868 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5869 "TWI $dst\n\t" 5870 "ISYNC" %} 5871 size(12); 5872 ins_encode( enc_ld_ac(dst, mem) ); 5873 ins_pipe(pipe_class_memory); 5874%} 5875 5876// LoadP + CastP2L 5877instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5878 match(Set dst (CastP2X (LoadP mem))); 5879 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5880 ins_cost(MEMORY_REF_COST); 5881 5882 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5883 size(4); 5884 ins_encode( enc_ld(dst, mem) ); 5885 ins_pipe(pipe_class_memory); 5886%} 5887 5888// Load compressed klass pointer. 5889instruct loadNKlass(iRegNdst dst, memory mem) %{ 5890 match(Set dst (LoadNKlass mem)); 5891 ins_cost(MEMORY_REF_COST); 5892 5893 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5894 size(4); 5895 ins_encode( enc_lwz(dst, mem) ); 5896 ins_pipe(pipe_class_memory); 5897%} 5898 5899// Load Klass Pointer 5900instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5901 match(Set dst (LoadKlass mem)); 5902 ins_cost(MEMORY_REF_COST); 5903 5904 format %{ "LD $dst, $mem \t// klass ptr" %} 5905 size(4); 5906 ins_encode( enc_ld(dst, mem) ); 5907 ins_pipe(pipe_class_memory); 5908%} 5909 5910// Load Float 5911instruct loadF(regF dst, memory mem) %{ 5912 match(Set dst (LoadF mem)); 5913 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5914 ins_cost(MEMORY_REF_COST); 5915 5916 format %{ "LFS $dst, $mem" %} 5917 size(4); 5918 ins_encode %{ 5919 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5920 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5921 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5922 %} 5923 ins_pipe(pipe_class_memory); 5924%} 5925 5926// Load Float acquire. 5927instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5928 match(Set dst (LoadF mem)); 5929 effect(TEMP cr0); 5930 ins_cost(3*MEMORY_REF_COST); 5931 5932 format %{ "LFS $dst, $mem \t// acquire\n\t" 5933 "FCMPU cr0, $dst, $dst\n\t" 5934 "BNE cr0, next\n" 5935 "next:\n\t" 5936 "ISYNC" %} 5937 size(16); 5938 ins_encode %{ 5939 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5940 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5941 Label next; 5942 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5943 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5944 __ bne(CCR0, next); 5945 __ bind(next); 5946 __ isync(); 5947 %} 5948 ins_pipe(pipe_class_memory); 5949%} 5950 5951// Load Double - aligned 5952instruct loadD(regD dst, memory mem) %{ 5953 match(Set dst (LoadD mem)); 5954 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5955 ins_cost(MEMORY_REF_COST); 5956 5957 format %{ "LFD $dst, $mem" %} 5958 size(4); 5959 ins_encode( enc_lfd(dst, mem) ); 5960 ins_pipe(pipe_class_memory); 5961%} 5962 5963// Load Double - aligned acquire. 5964instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5965 match(Set dst (LoadD mem)); 5966 effect(TEMP cr0); 5967 ins_cost(3*MEMORY_REF_COST); 5968 5969 format %{ "LFD $dst, $mem \t// acquire\n\t" 5970 "FCMPU cr0, $dst, $dst\n\t" 5971 "BNE cr0, next\n" 5972 "next:\n\t" 5973 "ISYNC" %} 5974 size(16); 5975 ins_encode %{ 5976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5977 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5978 Label next; 5979 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5980 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5981 __ bne(CCR0, next); 5982 __ bind(next); 5983 __ isync(); 5984 %} 5985 ins_pipe(pipe_class_memory); 5986%} 5987 5988// Load Double - UNaligned 5989instruct loadD_unaligned(regD dst, memory mem) %{ 5990 match(Set dst (LoadD_unaligned mem)); 5991 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5992 ins_cost(MEMORY_REF_COST); 5993 5994 format %{ "LFD $dst, $mem" %} 5995 size(4); 5996 ins_encode( enc_lfd(dst, mem) ); 5997 ins_pipe(pipe_class_memory); 5998%} 5999 6000//----------Constants-------------------------------------------------------- 6001 6002// Load MachConstantTableBase: add hi offset to global toc. 6003// TODO: Handle hidden register r29 in bundler! 6004instruct loadToc_hi(iRegLdst dst) %{ 6005 effect(DEF dst); 6006 ins_cost(DEFAULT_COST); 6007 6008 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 6009 size(4); 6010 ins_encode %{ 6011 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6012 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 6013 %} 6014 ins_pipe(pipe_class_default); 6015%} 6016 6017// Load MachConstantTableBase: add lo offset to global toc. 6018instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 6019 effect(DEF dst, USE src); 6020 ins_cost(DEFAULT_COST); 6021 6022 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 6023 size(4); 6024 ins_encode %{ 6025 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6026 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 6027 %} 6028 ins_pipe(pipe_class_default); 6029%} 6030 6031// Load 16-bit integer constant 0xssss???? 6032instruct loadConI16(iRegIdst dst, immI16 src) %{ 6033 match(Set dst src); 6034 6035 format %{ "LI $dst, $src" %} 6036 size(4); 6037 ins_encode %{ 6038 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6039 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6040 %} 6041 ins_pipe(pipe_class_default); 6042%} 6043 6044// Load integer constant 0x????0000 6045instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 6046 match(Set dst src); 6047 ins_cost(DEFAULT_COST); 6048 6049 format %{ "LIS $dst, $src.hi" %} 6050 size(4); 6051 ins_encode %{ 6052 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6053 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 6054 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6055 %} 6056 ins_pipe(pipe_class_default); 6057%} 6058 6059// Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 6060// and sign extended), this adds the low 16 bits. 6061instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 6062 // no match-rule, false predicate 6063 effect(DEF dst, USE src1, USE src2); 6064 predicate(false); 6065 6066 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 6067 size(4); 6068 ins_encode %{ 6069 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6070 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6071 %} 6072 ins_pipe(pipe_class_default); 6073%} 6074 6075instruct loadConI_Ex(iRegIdst dst, immI src) %{ 6076 match(Set dst src); 6077 ins_cost(DEFAULT_COST*2); 6078 6079 expand %{ 6080 // Would like to use $src$$constant. 6081 immI16 srcLo %{ _opnds[1]->constant() %} 6082 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6083 immIhi16 srcHi %{ _opnds[1]->constant() %} 6084 iRegIdst tmpI; 6085 loadConIhi16(tmpI, srcHi); 6086 loadConI32_lo16(dst, tmpI, srcLo); 6087 %} 6088%} 6089 6090// No constant pool entries required. 6091instruct loadConL16(iRegLdst dst, immL16 src) %{ 6092 match(Set dst src); 6093 6094 format %{ "LI $dst, $src \t// long" %} 6095 size(4); 6096 ins_encode %{ 6097 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6098 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 6099 %} 6100 ins_pipe(pipe_class_default); 6101%} 6102 6103// Load long constant 0xssssssss????0000 6104instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 6105 match(Set dst src); 6106 ins_cost(DEFAULT_COST); 6107 6108 format %{ "LIS $dst, $src.hi \t// long" %} 6109 size(4); 6110 ins_encode %{ 6111 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6112 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 6113 %} 6114 ins_pipe(pipe_class_default); 6115%} 6116 6117// To load a 32 bit constant: merge lower 16 bits into already loaded 6118// high 16 bits. 6119instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 6120 // no match-rule, false predicate 6121 effect(DEF dst, USE src1, USE src2); 6122 predicate(false); 6123 6124 format %{ "ORI $dst, $src1, $src2.lo" %} 6125 size(4); 6126 ins_encode %{ 6127 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6128 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 6129 %} 6130 ins_pipe(pipe_class_default); 6131%} 6132 6133// Load 32-bit long constant 6134instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 6135 match(Set dst src); 6136 ins_cost(DEFAULT_COST*2); 6137 6138 expand %{ 6139 // Would like to use $src$$constant. 6140 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 6141 // srcHi can be 0000 if srcLo sign-extends to a negative number. 6142 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 6143 iRegLdst tmpL; 6144 loadConL32hi16(tmpL, srcHi); 6145 loadConL32_lo16(dst, tmpL, srcLo); 6146 %} 6147%} 6148 6149// Load long constant 0x????000000000000. 6150instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 6151 match(Set dst src); 6152 ins_cost(DEFAULT_COST); 6153 6154 expand %{ 6155 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 6156 immI shift32 %{ 32 %} 6157 iRegLdst tmpL; 6158 loadConL32hi16(tmpL, srcHi); 6159 lshiftL_regL_immI(dst, tmpL, shift32); 6160 %} 6161%} 6162 6163// Expand node for constant pool load: small offset. 6164instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 6165 effect(DEF dst, USE src, USE toc); 6166 ins_cost(MEMORY_REF_COST); 6167 6168 ins_num_consts(1); 6169 // Needed so that CallDynamicJavaDirect can compute the address of this 6170 // instruction for relocation. 6171 ins_field_cbuf_insts_offset(int); 6172 6173 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 6174 size(4); 6175 ins_encode( enc_load_long_constL(dst, src, toc) ); 6176 ins_pipe(pipe_class_memory); 6177%} 6178 6179// Expand node for constant pool load: large offset. 6180instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 6181 effect(DEF dst, USE src, USE toc); 6182 predicate(false); 6183 6184 ins_num_consts(1); 6185 ins_field_const_toc_offset(int); 6186 // Needed so that CallDynamicJavaDirect can compute the address of this 6187 // instruction for relocation. 6188 ins_field_cbuf_insts_offset(int); 6189 6190 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 6191 size(4); 6192 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 6193 ins_pipe(pipe_class_default); 6194%} 6195 6196// Expand node for constant pool load: large offset. 6197// No constant pool entries required. 6198instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 6199 effect(DEF dst, USE src, USE base); 6200 predicate(false); 6201 6202 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 6203 6204 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 6205 size(4); 6206 ins_encode %{ 6207 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6208 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6209 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6210 %} 6211 ins_pipe(pipe_class_memory); 6212%} 6213 6214// Load long constant from constant table. Expand in case of 6215// offset > 16 bit is needed. 6216// Adlc adds toc node MachConstantTableBase. 6217instruct loadConL_Ex(iRegLdst dst, immL src) %{ 6218 match(Set dst src); 6219 ins_cost(MEMORY_REF_COST); 6220 6221 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 6222 // We can not inline the enc_class for the expand as that does not support constanttablebase. 6223 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 6224%} 6225 6226// Load NULL as compressed oop. 6227instruct loadConN0(iRegNdst dst, immN_0 src) %{ 6228 match(Set dst src); 6229 ins_cost(DEFAULT_COST); 6230 6231 format %{ "LI $dst, $src \t// compressed ptr" %} 6232 size(4); 6233 ins_encode %{ 6234 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6235 __ li($dst$$Register, 0); 6236 %} 6237 ins_pipe(pipe_class_default); 6238%} 6239 6240// Load hi part of compressed oop constant. 6241instruct loadConN_hi(iRegNdst dst, immN src) %{ 6242 effect(DEF dst, USE src); 6243 ins_cost(DEFAULT_COST); 6244 6245 format %{ "LIS $dst, $src \t// narrow oop hi" %} 6246 size(4); 6247 ins_encode %{ 6248 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6249 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 6250 %} 6251 ins_pipe(pipe_class_default); 6252%} 6253 6254// Add lo part of compressed oop constant to already loaded hi part. 6255instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 6256 effect(DEF dst, USE src1, USE src2); 6257 ins_cost(DEFAULT_COST); 6258 6259 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 6260 size(4); 6261 ins_encode %{ 6262 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6263 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6264 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 6265 RelocationHolder rspec = oop_Relocation::spec(oop_index); 6266 __ relocate(rspec, 1); 6267 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 6268 %} 6269 ins_pipe(pipe_class_default); 6270%} 6271 6272instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 6273 effect(DEF dst, USE src, USE shift, USE mask_begin); 6274 6275 size(4); 6276 ins_encode %{ 6277 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 6278 %} 6279 ins_pipe(pipe_class_default); 6280%} 6281 6282// Needed to postalloc expand loadConN: ConN is loaded as ConI 6283// leaving the upper 32 bits with sign-extension bits. 6284// This clears these bits: dst = src & 0xFFFFFFFF. 6285// TODO: Eventually call this maskN_regN_FFFFFFFF. 6286instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 6287 effect(DEF dst, USE src); 6288 predicate(false); 6289 6290 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 6291 size(4); 6292 ins_encode %{ 6293 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6294 __ clrldi($dst$$Register, $src$$Register, 0x20); 6295 %} 6296 ins_pipe(pipe_class_default); 6297%} 6298 6299// Optimize DecodeN for disjoint base. 6300// Load base of compressed oops into a register 6301instruct loadBase(iRegLdst dst) %{ 6302 effect(DEF dst); 6303 6304 format %{ "LoadConst $dst, heapbase" %} 6305 ins_encode %{ 6306 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6307 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 6308 %} 6309 ins_pipe(pipe_class_default); 6310%} 6311 6312// Loading ConN must be postalloc expanded so that edges between 6313// the nodes are safe. They may not interfere with a safepoint. 6314// GL TODO: This needs three instructions: better put this into the constant pool. 6315instruct loadConN_Ex(iRegNdst dst, immN src) %{ 6316 match(Set dst src); 6317 ins_cost(DEFAULT_COST*2); 6318 6319 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6320 postalloc_expand %{ 6321 MachNode *m1 = new loadConN_hiNode(); 6322 MachNode *m2 = new loadConN_loNode(); 6323 MachNode *m3 = new clearMs32bNode(); 6324 m1->add_req(NULL); 6325 m2->add_req(NULL, m1); 6326 m3->add_req(NULL, m2); 6327 m1->_opnds[0] = op_dst; 6328 m1->_opnds[1] = op_src; 6329 m2->_opnds[0] = op_dst; 6330 m2->_opnds[1] = op_dst; 6331 m2->_opnds[2] = op_src; 6332 m3->_opnds[0] = op_dst; 6333 m3->_opnds[1] = op_dst; 6334 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6335 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6336 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6337 nodes->push(m1); 6338 nodes->push(m2); 6339 nodes->push(m3); 6340 %} 6341%} 6342 6343// We have seen a safepoint between the hi and lo parts, and this node was handled 6344// as an oop. Therefore this needs a match rule so that build_oop_map knows this is 6345// not a narrow oop. 6346instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 6347 match(Set dst src); 6348 effect(DEF dst, USE src); 6349 ins_cost(DEFAULT_COST); 6350 6351 format %{ "LIS $dst, $src \t// narrow klass hi" %} 6352 size(4); 6353 ins_encode %{ 6354 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 6355 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 6356 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 6357 %} 6358 ins_pipe(pipe_class_default); 6359%} 6360 6361// As loadConNKlass_hi this must be recognized as narrow klass, not oop! 6362instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6363 match(Set dst src1); 6364 effect(TEMP src2); 6365 ins_cost(DEFAULT_COST); 6366 6367 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 6368 size(4); 6369 ins_encode %{ 6370 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6371 __ clrldi($dst$$Register, $src2$$Register, 0x20); 6372 %} 6373 ins_pipe(pipe_class_default); 6374%} 6375 6376// This needs a match rule so that build_oop_map knows this is 6377// not a narrow oop. 6378instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 6379 match(Set dst src1); 6380 effect(TEMP src2); 6381 ins_cost(DEFAULT_COST); 6382 6383 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 6384 size(4); 6385 ins_encode %{ 6386 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 6387 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 6388 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 6389 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 6390 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 6391 6392 __ relocate(rspec, 1); 6393 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 6394 %} 6395 ins_pipe(pipe_class_default); 6396%} 6397 6398// Loading ConNKlass must be postalloc expanded so that edges between 6399// the nodes are safe. They may not interfere with a safepoint. 6400instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 6401 match(Set dst src); 6402 ins_cost(DEFAULT_COST*2); 6403 6404 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 6405 postalloc_expand %{ 6406 // Load high bits into register. Sign extended. 6407 MachNode *m1 = new loadConNKlass_hiNode(); 6408 m1->add_req(NULL); 6409 m1->_opnds[0] = op_dst; 6410 m1->_opnds[1] = op_src; 6411 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6412 nodes->push(m1); 6413 6414 MachNode *m2 = m1; 6415 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 6416 // Value might be 1-extended. Mask out these bits. 6417 m2 = new loadConNKlass_maskNode(); 6418 m2->add_req(NULL, m1); 6419 m2->_opnds[0] = op_dst; 6420 m2->_opnds[1] = op_src; 6421 m2->_opnds[2] = op_dst; 6422 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6423 nodes->push(m2); 6424 } 6425 6426 MachNode *m3 = new loadConNKlass_loNode(); 6427 m3->add_req(NULL, m2); 6428 m3->_opnds[0] = op_dst; 6429 m3->_opnds[1] = op_src; 6430 m3->_opnds[2] = op_dst; 6431 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6432 nodes->push(m3); 6433 %} 6434%} 6435 6436// 0x1 is used in object initialization (initial object header). 6437// No constant pool entries required. 6438instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6439 match(Set dst src); 6440 6441 format %{ "LI $dst, $src \t// ptr" %} 6442 size(4); 6443 ins_encode %{ 6444 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6445 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6446 %} 6447 ins_pipe(pipe_class_default); 6448%} 6449 6450// Expand node for constant pool load: small offset. 6451// The match rule is needed to generate the correct bottom_type(), 6452// however this node should never match. The use of predicate is not 6453// possible since ADLC forbids predicates for chain rules. The higher 6454// costs do not prevent matching in this case. For that reason the 6455// operand immP_NM with predicate(false) is used. 6456instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6457 match(Set dst src); 6458 effect(TEMP toc); 6459 6460 ins_num_consts(1); 6461 6462 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6463 size(4); 6464 ins_encode( enc_load_long_constP(dst, src, toc) ); 6465 ins_pipe(pipe_class_memory); 6466%} 6467 6468// Expand node for constant pool load: large offset. 6469instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6470 effect(DEF dst, USE src, USE toc); 6471 predicate(false); 6472 6473 ins_num_consts(1); 6474 ins_field_const_toc_offset(int); 6475 6476 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6477 size(4); 6478 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6479 ins_pipe(pipe_class_default); 6480%} 6481 6482// Expand node for constant pool load: large offset. 6483instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6484 match(Set dst src); 6485 effect(TEMP base); 6486 6487 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6488 6489 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6490 size(4); 6491 ins_encode %{ 6492 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6493 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6494 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6495 %} 6496 ins_pipe(pipe_class_memory); 6497%} 6498 6499// Load pointer constant from constant table. Expand in case an 6500// offset > 16 bit is needed. 6501// Adlc adds toc node MachConstantTableBase. 6502instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6503 match(Set dst src); 6504 ins_cost(MEMORY_REF_COST); 6505 6506 // This rule does not use "expand" because then 6507 // the result type is not known to be an Oop. An ADLC 6508 // enhancement will be needed to make that work - not worth it! 6509 6510 // If this instruction rematerializes, it prolongs the live range 6511 // of the toc node, causing illegal graphs. 6512 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6513 ins_cannot_rematerialize(true); 6514 6515 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6516 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6517%} 6518 6519// Expand node for constant pool load: small offset. 6520instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6521 effect(DEF dst, USE src, USE toc); 6522 ins_cost(MEMORY_REF_COST); 6523 6524 ins_num_consts(1); 6525 6526 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6527 size(4); 6528 ins_encode %{ 6529 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6530 address float_address = __ float_constant($src$$constant); 6531 if (float_address == NULL) { 6532 ciEnv::current()->record_out_of_memory_failure(); 6533 return; 6534 } 6535 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6536 %} 6537 ins_pipe(pipe_class_memory); 6538%} 6539 6540// Expand node for constant pool load: large offset. 6541instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6542 effect(DEF dst, USE src, USE toc); 6543 ins_cost(MEMORY_REF_COST); 6544 6545 ins_num_consts(1); 6546 6547 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6548 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6549 "ADDIS $toc, $toc, -offset_hi"%} 6550 size(12); 6551 ins_encode %{ 6552 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6553 FloatRegister Rdst = $dst$$FloatRegister; 6554 Register Rtoc = $toc$$Register; 6555 address float_address = __ float_constant($src$$constant); 6556 if (float_address == NULL) { 6557 ciEnv::current()->record_out_of_memory_failure(); 6558 return; 6559 } 6560 int offset = __ offset_to_method_toc(float_address); 6561 int hi = (offset + (1<<15))>>16; 6562 int lo = offset - hi * (1<<16); 6563 6564 __ addis(Rtoc, Rtoc, hi); 6565 __ lfs(Rdst, lo, Rtoc); 6566 __ addis(Rtoc, Rtoc, -hi); 6567 %} 6568 ins_pipe(pipe_class_memory); 6569%} 6570 6571// Adlc adds toc node MachConstantTableBase. 6572instruct loadConF_Ex(regF dst, immF src) %{ 6573 match(Set dst src); 6574 ins_cost(MEMORY_REF_COST); 6575 6576 // See loadConP. 6577 ins_cannot_rematerialize(true); 6578 6579 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6580 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6581%} 6582 6583// Expand node for constant pool load: small offset. 6584instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6585 effect(DEF dst, USE src, USE toc); 6586 ins_cost(MEMORY_REF_COST); 6587 6588 ins_num_consts(1); 6589 6590 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6591 size(4); 6592 ins_encode %{ 6593 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6594 address float_address = __ double_constant($src$$constant); 6595 if (float_address == NULL) { 6596 ciEnv::current()->record_out_of_memory_failure(); 6597 return; 6598 } 6599 int offset = __ offset_to_method_toc(float_address); 6600 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6601 %} 6602 ins_pipe(pipe_class_memory); 6603%} 6604 6605// Expand node for constant pool load: large offset. 6606instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6607 effect(DEF dst, USE src, USE toc); 6608 ins_cost(MEMORY_REF_COST); 6609 6610 ins_num_consts(1); 6611 6612 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6613 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6614 "ADDIS $toc, $toc, -offset_hi" %} 6615 size(12); 6616 ins_encode %{ 6617 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6618 FloatRegister Rdst = $dst$$FloatRegister; 6619 Register Rtoc = $toc$$Register; 6620 address float_address = __ double_constant($src$$constant); 6621 if (float_address == NULL) { 6622 ciEnv::current()->record_out_of_memory_failure(); 6623 return; 6624 } 6625 int offset = __ offset_to_method_toc(float_address); 6626 int hi = (offset + (1<<15))>>16; 6627 int lo = offset - hi * (1<<16); 6628 6629 __ addis(Rtoc, Rtoc, hi); 6630 __ lfd(Rdst, lo, Rtoc); 6631 __ addis(Rtoc, Rtoc, -hi); 6632 %} 6633 ins_pipe(pipe_class_memory); 6634%} 6635 6636// Adlc adds toc node MachConstantTableBase. 6637instruct loadConD_Ex(regD dst, immD src) %{ 6638 match(Set dst src); 6639 ins_cost(MEMORY_REF_COST); 6640 6641 // See loadConP. 6642 ins_cannot_rematerialize(true); 6643 6644 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6645 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6646%} 6647 6648// Prefetch instructions. 6649// Must be safe to execute with invalid address (cannot fault). 6650 6651// Special prefetch versions which use the dcbz instruction. 6652instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6653 match(PrefetchAllocation (AddP mem src)); 6654 predicate(AllocatePrefetchStyle == 3); 6655 ins_cost(MEMORY_REF_COST); 6656 6657 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6658 size(4); 6659 ins_encode %{ 6660 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6661 __ dcbz($src$$Register, $mem$$base$$Register); 6662 %} 6663 ins_pipe(pipe_class_memory); 6664%} 6665 6666instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6667 match(PrefetchAllocation mem); 6668 predicate(AllocatePrefetchStyle == 3); 6669 ins_cost(MEMORY_REF_COST); 6670 6671 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6672 size(4); 6673 ins_encode %{ 6674 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6675 __ dcbz($mem$$base$$Register); 6676 %} 6677 ins_pipe(pipe_class_memory); 6678%} 6679 6680instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6681 match(PrefetchAllocation (AddP mem src)); 6682 predicate(AllocatePrefetchStyle != 3); 6683 ins_cost(MEMORY_REF_COST); 6684 6685 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6686 size(4); 6687 ins_encode %{ 6688 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6689 __ dcbtst($src$$Register, $mem$$base$$Register); 6690 %} 6691 ins_pipe(pipe_class_memory); 6692%} 6693 6694instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6695 match(PrefetchAllocation mem); 6696 predicate(AllocatePrefetchStyle != 3); 6697 ins_cost(MEMORY_REF_COST); 6698 6699 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6700 size(4); 6701 ins_encode %{ 6702 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6703 __ dcbtst($mem$$base$$Register); 6704 %} 6705 ins_pipe(pipe_class_memory); 6706%} 6707 6708//----------Store Instructions------------------------------------------------- 6709 6710// Store Byte 6711instruct storeB(memory mem, iRegIsrc src) %{ 6712 match(Set mem (StoreB mem src)); 6713 ins_cost(MEMORY_REF_COST); 6714 6715 format %{ "STB $src, $mem \t// byte" %} 6716 size(4); 6717 ins_encode %{ 6718 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6719 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6720 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6721 %} 6722 ins_pipe(pipe_class_memory); 6723%} 6724 6725// Store Char/Short 6726instruct storeC(memory mem, iRegIsrc src) %{ 6727 match(Set mem (StoreC mem src)); 6728 ins_cost(MEMORY_REF_COST); 6729 6730 format %{ "STH $src, $mem \t// short" %} 6731 size(4); 6732 ins_encode %{ 6733 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6734 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6735 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6736 %} 6737 ins_pipe(pipe_class_memory); 6738%} 6739 6740// Store Integer 6741instruct storeI(memory mem, iRegIsrc src) %{ 6742 match(Set mem (StoreI mem src)); 6743 ins_cost(MEMORY_REF_COST); 6744 6745 format %{ "STW $src, $mem" %} 6746 size(4); 6747 ins_encode( enc_stw(src, mem) ); 6748 ins_pipe(pipe_class_memory); 6749%} 6750 6751// ConvL2I + StoreI. 6752instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6753 match(Set mem (StoreI mem (ConvL2I src))); 6754 ins_cost(MEMORY_REF_COST); 6755 6756 format %{ "STW l2i($src), $mem" %} 6757 size(4); 6758 ins_encode( enc_stw(src, mem) ); 6759 ins_pipe(pipe_class_memory); 6760%} 6761 6762// Store Long 6763instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6764 match(Set mem (StoreL mem src)); 6765 ins_cost(MEMORY_REF_COST); 6766 6767 format %{ "STD $src, $mem \t// long" %} 6768 size(4); 6769 ins_encode( enc_std(src, mem) ); 6770 ins_pipe(pipe_class_memory); 6771%} 6772 6773// Store super word nodes. 6774 6775// Store Aligned Packed Byte long register to memory 6776instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6777 predicate(n->as_StoreVector()->memory_size() == 8); 6778 match(Set mem (StoreVector mem src)); 6779 ins_cost(MEMORY_REF_COST); 6780 6781 format %{ "STD $mem, $src \t// packed8B" %} 6782 size(4); 6783 ins_encode( enc_std(src, mem) ); 6784 ins_pipe(pipe_class_memory); 6785%} 6786 6787// Store Packed Byte long register to memory 6788instruct storeV16(indirect mem, vecX src) %{ 6789 predicate(n->as_StoreVector()->memory_size() == 16); 6790 match(Set mem (StoreVector mem src)); 6791 ins_cost(MEMORY_REF_COST); 6792 6793 format %{ "STXVD2X $mem, $src \t// store 16-byte Vector" %} 6794 size(4); 6795 ins_encode %{ 6796 __ stxvd2x($src$$VectorSRegister, $mem$$Register); 6797 %} 6798 ins_pipe(pipe_class_default); 6799%} 6800 6801// Store Compressed Oop 6802instruct storeN(memory dst, iRegN_P2N src) %{ 6803 match(Set dst (StoreN dst src)); 6804 ins_cost(MEMORY_REF_COST); 6805 6806 format %{ "STW $src, $dst \t// compressed oop" %} 6807 size(4); 6808 ins_encode( enc_stw(src, dst) ); 6809 ins_pipe(pipe_class_memory); 6810%} 6811 6812// Store Compressed KLass 6813instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6814 match(Set dst (StoreNKlass dst src)); 6815 ins_cost(MEMORY_REF_COST); 6816 6817 format %{ "STW $src, $dst \t// compressed klass" %} 6818 size(4); 6819 ins_encode( enc_stw(src, dst) ); 6820 ins_pipe(pipe_class_memory); 6821%} 6822 6823// Store Pointer 6824instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6825 match(Set dst (StoreP dst src)); 6826 ins_cost(MEMORY_REF_COST); 6827 6828 format %{ "STD $src, $dst \t// ptr" %} 6829 size(4); 6830 ins_encode( enc_std(src, dst) ); 6831 ins_pipe(pipe_class_memory); 6832%} 6833 6834// Store Float 6835instruct storeF(memory mem, regF src) %{ 6836 match(Set mem (StoreF mem src)); 6837 ins_cost(MEMORY_REF_COST); 6838 6839 format %{ "STFS $src, $mem" %} 6840 size(4); 6841 ins_encode( enc_stfs(src, mem) ); 6842 ins_pipe(pipe_class_memory); 6843%} 6844 6845// Store Double 6846instruct storeD(memory mem, regD src) %{ 6847 match(Set mem (StoreD mem src)); 6848 ins_cost(MEMORY_REF_COST); 6849 6850 format %{ "STFD $src, $mem" %} 6851 size(4); 6852 ins_encode( enc_stfd(src, mem) ); 6853 ins_pipe(pipe_class_memory); 6854%} 6855 6856//----------Store Instructions With Zeros-------------------------------------- 6857 6858// Card-mark for CMS garbage collection. 6859// This cardmark does an optimization so that it must not always 6860// do a releasing store. For this, it gets the address of 6861// CMSCollectorCardTableBarrierSetBSExt::_requires_release as input. 6862// (Using releaseFieldAddr in the match rule is a hack.) 6863instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6864 match(Set mem (StoreCM mem releaseFieldAddr)); 6865 effect(TEMP crx); 6866 predicate(false); 6867 ins_cost(MEMORY_REF_COST); 6868 6869 // See loadConP. 6870 ins_cannot_rematerialize(true); 6871 6872 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6873 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6874 ins_pipe(pipe_class_memory); 6875%} 6876 6877// Card-mark for CMS garbage collection. 6878// This cardmark does an optimization so that it must not always 6879// do a releasing store. For this, it needs the constant address of 6880// CMSCollectorCardTableBarrierSetBSExt::_requires_release. 6881// This constant address is split off here by expand so we can use 6882// adlc / matcher functionality to load it from the constant section. 6883instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6884 match(Set mem (StoreCM mem zero)); 6885 predicate(UseConcMarkSweepGC); 6886 6887 expand %{ 6888 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableBarrierSetBSExt::requires_release_address() */ %} 6889 iRegLdst releaseFieldAddress; 6890 flagsReg crx; 6891 loadConL_Ex(releaseFieldAddress, baseImm); 6892 storeCM_CMS(mem, releaseFieldAddress, crx); 6893 %} 6894%} 6895 6896instruct storeCM_G1(memory mem, immI_0 zero) %{ 6897 match(Set mem (StoreCM mem zero)); 6898 predicate(UseG1GC); 6899 ins_cost(MEMORY_REF_COST); 6900 6901 ins_cannot_rematerialize(true); 6902 6903 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6904 size(8); 6905 ins_encode %{ 6906 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6907 __ li(R0, 0); 6908 //__ release(); // G1: oops are allowed to get visible after dirty marking 6909 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6910 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6911 %} 6912 ins_pipe(pipe_class_memory); 6913%} 6914 6915// Convert oop pointer into compressed form. 6916 6917// Nodes for postalloc expand. 6918 6919// Shift node for expand. 6920instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6921 // The match rule is needed to make it a 'MachTypeNode'! 6922 match(Set dst (EncodeP src)); 6923 predicate(false); 6924 6925 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6926 size(4); 6927 ins_encode %{ 6928 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6929 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6930 %} 6931 ins_pipe(pipe_class_default); 6932%} 6933 6934// Add node for expand. 6935instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6936 // The match rule is needed to make it a 'MachTypeNode'! 6937 match(Set dst (EncodeP src)); 6938 predicate(false); 6939 6940 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6941 ins_encode %{ 6942 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6943 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6944 %} 6945 ins_pipe(pipe_class_default); 6946%} 6947 6948// Conditional sub base. 6949instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6950 // The match rule is needed to make it a 'MachTypeNode'! 6951 match(Set dst (EncodeP (Binary crx src1))); 6952 predicate(false); 6953 6954 format %{ "BEQ $crx, done\n\t" 6955 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6956 "done:" %} 6957 ins_encode %{ 6958 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6959 Label done; 6960 __ beq($crx$$CondRegister, done); 6961 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6962 __ bind(done); 6963 %} 6964 ins_pipe(pipe_class_default); 6965%} 6966 6967// Power 7 can use isel instruction 6968instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6969 // The match rule is needed to make it a 'MachTypeNode'! 6970 match(Set dst (EncodeP (Binary crx src1))); 6971 predicate(false); 6972 6973 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6974 size(4); 6975 ins_encode %{ 6976 // This is a Power7 instruction for which no machine description exists. 6977 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6978 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6979 %} 6980 ins_pipe(pipe_class_default); 6981%} 6982 6983// Disjoint narrow oop base. 6984instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6985 match(Set dst (EncodeP src)); 6986 predicate(Universe::narrow_oop_base_disjoint()); 6987 6988 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6989 size(4); 6990 ins_encode %{ 6991 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6992 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6993 %} 6994 ins_pipe(pipe_class_default); 6995%} 6996 6997// shift != 0, base != 0 6998instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6999 match(Set dst (EncodeP src)); 7000 effect(TEMP crx); 7001 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 7002 Universe::narrow_oop_shift() != 0 && 7003 Universe::narrow_oop_base_overlaps()); 7004 7005 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 7006 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 7007%} 7008 7009// shift != 0, base != 0 7010instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 7011 match(Set dst (EncodeP src)); 7012 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 7013 Universe::narrow_oop_shift() != 0 && 7014 Universe::narrow_oop_base_overlaps()); 7015 7016 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 7017 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 7018%} 7019 7020// shift != 0, base == 0 7021// TODO: This is the same as encodeP_shift. Merge! 7022instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 7023 match(Set dst (EncodeP src)); 7024 predicate(Universe::narrow_oop_shift() != 0 && 7025 Universe::narrow_oop_base() ==0); 7026 7027 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 7028 size(4); 7029 ins_encode %{ 7030 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7031 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 7032 %} 7033 ins_pipe(pipe_class_default); 7034%} 7035 7036// Compressed OOPs with narrow_oop_shift == 0. 7037// shift == 0, base == 0 7038instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 7039 match(Set dst (EncodeP src)); 7040 predicate(Universe::narrow_oop_shift() == 0); 7041 7042 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 7043 // variable size, 0 or 4. 7044 ins_encode %{ 7045 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7046 __ mr_if_needed($dst$$Register, $src$$Register); 7047 %} 7048 ins_pipe(pipe_class_default); 7049%} 7050 7051// Decode nodes. 7052 7053// Shift node for expand. 7054instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 7055 // The match rule is needed to make it a 'MachTypeNode'! 7056 match(Set dst (DecodeN src)); 7057 predicate(false); 7058 7059 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 7060 size(4); 7061 ins_encode %{ 7062 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7063 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7064 %} 7065 ins_pipe(pipe_class_default); 7066%} 7067 7068// Add node for expand. 7069instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 7070 // The match rule is needed to make it a 'MachTypeNode'! 7071 match(Set dst (DecodeN src)); 7072 predicate(false); 7073 7074 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 7075 ins_encode %{ 7076 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7077 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7078 %} 7079 ins_pipe(pipe_class_default); 7080%} 7081 7082// conditianal add base for expand 7083instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 7084 // The match rule is needed to make it a 'MachTypeNode'! 7085 // NOTICE that the rule is nonsense - we just have to make sure that: 7086 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7087 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7088 match(Set dst (DecodeN (Binary crx src))); 7089 predicate(false); 7090 7091 format %{ "BEQ $crx, done\n\t" 7092 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 7093 "done:" %} 7094 ins_encode %{ 7095 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7096 Label done; 7097 __ beq($crx$$CondRegister, done); 7098 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 7099 __ bind(done); 7100 %} 7101 ins_pipe(pipe_class_default); 7102%} 7103 7104instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 7105 // The match rule is needed to make it a 'MachTypeNode'! 7106 // NOTICE that the rule is nonsense - we just have to make sure that: 7107 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 7108 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 7109 match(Set dst (DecodeN (Binary crx src1))); 7110 predicate(false); 7111 7112 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 7113 size(4); 7114 ins_encode %{ 7115 // This is a Power7 instruction for which no machine description exists. 7116 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7117 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 7118 %} 7119 ins_pipe(pipe_class_default); 7120%} 7121 7122// shift != 0, base != 0 7123instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7124 match(Set dst (DecodeN src)); 7125 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7126 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7127 Universe::narrow_oop_shift() != 0 && 7128 Universe::narrow_oop_base() != 0); 7129 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 7130 effect(TEMP crx); 7131 7132 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 7133 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 7134%} 7135 7136// shift != 0, base == 0 7137instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 7138 match(Set dst (DecodeN src)); 7139 predicate(Universe::narrow_oop_shift() != 0 && 7140 Universe::narrow_oop_base() == 0); 7141 7142 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 7143 size(4); 7144 ins_encode %{ 7145 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7146 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 7147 %} 7148 ins_pipe(pipe_class_default); 7149%} 7150 7151// Optimize DecodeN for disjoint base. 7152// Shift narrow oop and or it into register that already contains the heap base. 7153// Base == dst must hold, and is assured by construction in postaloc_expand. 7154instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 7155 match(Set dst (DecodeN src)); 7156 effect(TEMP base); 7157 predicate(false); 7158 7159 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 7160 size(4); 7161 ins_encode %{ 7162 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 7163 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 7164 %} 7165 ins_pipe(pipe_class_default); 7166%} 7167 7168// Optimize DecodeN for disjoint base. 7169// This node requires only one cycle on the critical path. 7170// We must postalloc_expand as we can not express use_def effects where 7171// the used register is L and the def'ed register P. 7172instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 7173 match(Set dst (DecodeN src)); 7174 effect(TEMP_DEF dst); 7175 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7176 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7177 Universe::narrow_oop_base_disjoint()); 7178 ins_cost(DEFAULT_COST); 7179 7180 format %{ "MOV $dst, heapbase \t\n" 7181 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 7182 postalloc_expand %{ 7183 loadBaseNode *n1 = new loadBaseNode(); 7184 n1->add_req(NULL); 7185 n1->_opnds[0] = op_dst; 7186 7187 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7188 n2->add_req(n_region, n_src, n1); 7189 n2->_opnds[0] = op_dst; 7190 n2->_opnds[1] = op_src; 7191 n2->_opnds[2] = op_dst; 7192 n2->_bottom_type = _bottom_type; 7193 7194 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7195 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7196 7197 nodes->push(n1); 7198 nodes->push(n2); 7199 %} 7200%} 7201 7202instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 7203 match(Set dst (DecodeN src)); 7204 effect(TEMP_DEF dst, TEMP crx); 7205 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7206 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 7207 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 7208 ins_cost(3 * DEFAULT_COST); 7209 7210 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 7211 postalloc_expand %{ 7212 loadBaseNode *n1 = new loadBaseNode(); 7213 n1->add_req(NULL); 7214 n1->_opnds[0] = op_dst; 7215 7216 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 7217 n_compare->add_req(n_region, n_src); 7218 n_compare->_opnds[0] = op_crx; 7219 n_compare->_opnds[1] = op_src; 7220 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 7221 7222 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 7223 n2->add_req(n_region, n_src, n1); 7224 n2->_opnds[0] = op_dst; 7225 n2->_opnds[1] = op_src; 7226 n2->_opnds[2] = op_dst; 7227 n2->_bottom_type = _bottom_type; 7228 7229 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 7230 n_cond_set->add_req(n_region, n_compare, n2); 7231 n_cond_set->_opnds[0] = op_dst; 7232 n_cond_set->_opnds[1] = op_crx; 7233 n_cond_set->_opnds[2] = op_dst; 7234 n_cond_set->_bottom_type = _bottom_type; 7235 7236 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 7237 ra_->set_oop(n_cond_set, true); 7238 7239 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7240 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 7241 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7242 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7243 7244 nodes->push(n1); 7245 nodes->push(n_compare); 7246 nodes->push(n2); 7247 nodes->push(n_cond_set); 7248 %} 7249%} 7250 7251// src != 0, shift != 0, base != 0 7252instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 7253 match(Set dst (DecodeN src)); 7254 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7255 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 7256 Universe::narrow_oop_shift() != 0 && 7257 Universe::narrow_oop_base() != 0); 7258 ins_cost(2 * DEFAULT_COST); 7259 7260 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 7261 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 7262%} 7263 7264// Compressed OOPs with narrow_oop_shift == 0. 7265instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 7266 match(Set dst (DecodeN src)); 7267 predicate(Universe::narrow_oop_shift() == 0); 7268 ins_cost(DEFAULT_COST); 7269 7270 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 7271 // variable size, 0 or 4. 7272 ins_encode %{ 7273 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7274 __ mr_if_needed($dst$$Register, $src$$Register); 7275 %} 7276 ins_pipe(pipe_class_default); 7277%} 7278 7279// Convert compressed oop into int for vectors alignment masking. 7280instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 7281 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7282 predicate(Universe::narrow_oop_shift() == 0); 7283 ins_cost(DEFAULT_COST); 7284 7285 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 7286 // variable size, 0 or 4. 7287 ins_encode %{ 7288 // TODO: PPC port $archOpcode(ppc64Opcode_or); 7289 __ mr_if_needed($dst$$Register, $src$$Register); 7290 %} 7291 ins_pipe(pipe_class_default); 7292%} 7293 7294// Convert klass pointer into compressed form. 7295 7296// Nodes for postalloc expand. 7297 7298// Shift node for expand. 7299instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 7300 // The match rule is needed to make it a 'MachTypeNode'! 7301 match(Set dst (EncodePKlass src)); 7302 predicate(false); 7303 7304 format %{ "SRDI $dst, $src, 3 \t// encode" %} 7305 size(4); 7306 ins_encode %{ 7307 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7308 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7309 %} 7310 ins_pipe(pipe_class_default); 7311%} 7312 7313// Add node for expand. 7314instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7315 // The match rule is needed to make it a 'MachTypeNode'! 7316 match(Set dst (EncodePKlass (Binary base src))); 7317 predicate(false); 7318 7319 format %{ "SUB $dst, $base, $src \t// encode" %} 7320 size(4); 7321 ins_encode %{ 7322 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 7323 __ subf($dst$$Register, $base$$Register, $src$$Register); 7324 %} 7325 ins_pipe(pipe_class_default); 7326%} 7327 7328// Disjoint narrow oop base. 7329instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 7330 match(Set dst (EncodePKlass src)); 7331 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 7332 7333 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 7334 size(4); 7335 ins_encode %{ 7336 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 7337 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 7338 %} 7339 ins_pipe(pipe_class_default); 7340%} 7341 7342// shift != 0, base != 0 7343instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 7344 match(Set dst (EncodePKlass (Binary base src))); 7345 predicate(false); 7346 7347 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7348 postalloc_expand %{ 7349 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 7350 n1->add_req(n_region, n_base, n_src); 7351 n1->_opnds[0] = op_dst; 7352 n1->_opnds[1] = op_base; 7353 n1->_opnds[2] = op_src; 7354 n1->_bottom_type = _bottom_type; 7355 7356 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 7357 n2->add_req(n_region, n1); 7358 n2->_opnds[0] = op_dst; 7359 n2->_opnds[1] = op_dst; 7360 n2->_bottom_type = _bottom_type; 7361 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7362 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7363 7364 nodes->push(n1); 7365 nodes->push(n2); 7366 %} 7367%} 7368 7369// shift != 0, base != 0 7370instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 7371 match(Set dst (EncodePKlass src)); 7372 //predicate(Universe::narrow_klass_shift() != 0 && 7373 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 7374 7375 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 7376 ins_cost(DEFAULT_COST*2); // Don't count constant. 7377 expand %{ 7378 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 7379 iRegLdst base; 7380 loadConL_Ex(base, baseImm); 7381 encodePKlass_not_null_Ex(dst, base, src); 7382 %} 7383%} 7384 7385// Decode nodes. 7386 7387// Shift node for expand. 7388instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 7389 // The match rule is needed to make it a 'MachTypeNode'! 7390 match(Set dst (DecodeNKlass src)); 7391 predicate(false); 7392 7393 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 7394 size(4); 7395 ins_encode %{ 7396 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 7397 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 7398 %} 7399 ins_pipe(pipe_class_default); 7400%} 7401 7402// Add node for expand. 7403 7404instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7405 // The match rule is needed to make it a 'MachTypeNode'! 7406 match(Set dst (DecodeNKlass (Binary base src))); 7407 predicate(false); 7408 7409 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7410 size(4); 7411 ins_encode %{ 7412 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7413 __ add($dst$$Register, $base$$Register, $src$$Register); 7414 %} 7415 ins_pipe(pipe_class_default); 7416%} 7417 7418// src != 0, shift != 0, base != 0 7419instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7420 match(Set dst (DecodeNKlass (Binary base src))); 7421 //effect(kill src); // We need a register for the immediate result after shifting. 7422 predicate(false); 7423 7424 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7425 postalloc_expand %{ 7426 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7427 n1->add_req(n_region, n_base, n_src); 7428 n1->_opnds[0] = op_dst; 7429 n1->_opnds[1] = op_base; 7430 n1->_opnds[2] = op_src; 7431 n1->_bottom_type = _bottom_type; 7432 7433 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7434 n2->add_req(n_region, n1); 7435 n2->_opnds[0] = op_dst; 7436 n2->_opnds[1] = op_dst; 7437 n2->_bottom_type = _bottom_type; 7438 7439 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7440 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7441 7442 nodes->push(n1); 7443 nodes->push(n2); 7444 %} 7445%} 7446 7447// src != 0, shift != 0, base != 0 7448instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7449 match(Set dst (DecodeNKlass src)); 7450 // predicate(Universe::narrow_klass_shift() != 0 && 7451 // Universe::narrow_klass_base() != 0); 7452 7453 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7454 7455 ins_cost(DEFAULT_COST*2); // Don't count constant. 7456 expand %{ 7457 // We add first, then we shift. Like this, we can get along with one register less. 7458 // But we have to load the base pre-shifted. 7459 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7460 iRegLdst base; 7461 loadConL_Ex(base, baseImm); 7462 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7463 %} 7464%} 7465 7466//----------MemBar Instructions----------------------------------------------- 7467// Memory barrier flavors 7468 7469instruct membar_acquire() %{ 7470 match(LoadFence); 7471 ins_cost(4*MEMORY_REF_COST); 7472 7473 format %{ "MEMBAR-acquire" %} 7474 size(4); 7475 ins_encode %{ 7476 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7477 __ acquire(); 7478 %} 7479 ins_pipe(pipe_class_default); 7480%} 7481 7482instruct unnecessary_membar_acquire() %{ 7483 match(MemBarAcquire); 7484 ins_cost(0); 7485 7486 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7487 size(0); 7488 ins_encode( /*empty*/ ); 7489 ins_pipe(pipe_class_default); 7490%} 7491 7492instruct membar_acquire_lock() %{ 7493 match(MemBarAcquireLock); 7494 ins_cost(0); 7495 7496 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7497 size(0); 7498 ins_encode( /*empty*/ ); 7499 ins_pipe(pipe_class_default); 7500%} 7501 7502instruct membar_release() %{ 7503 match(MemBarRelease); 7504 match(StoreFence); 7505 ins_cost(4*MEMORY_REF_COST); 7506 7507 format %{ "MEMBAR-release" %} 7508 size(4); 7509 ins_encode %{ 7510 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7511 __ release(); 7512 %} 7513 ins_pipe(pipe_class_default); 7514%} 7515 7516instruct membar_storestore() %{ 7517 match(MemBarStoreStore); 7518 ins_cost(4*MEMORY_REF_COST); 7519 7520 format %{ "MEMBAR-store-store" %} 7521 size(4); 7522 ins_encode %{ 7523 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7524 __ membar(Assembler::StoreStore); 7525 %} 7526 ins_pipe(pipe_class_default); 7527%} 7528 7529instruct membar_release_lock() %{ 7530 match(MemBarReleaseLock); 7531 ins_cost(0); 7532 7533 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7534 size(0); 7535 ins_encode( /*empty*/ ); 7536 ins_pipe(pipe_class_default); 7537%} 7538 7539instruct membar_volatile() %{ 7540 match(MemBarVolatile); 7541 ins_cost(4*MEMORY_REF_COST); 7542 7543 format %{ "MEMBAR-volatile" %} 7544 size(4); 7545 ins_encode %{ 7546 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7547 __ fence(); 7548 %} 7549 ins_pipe(pipe_class_default); 7550%} 7551 7552// This optimization is wrong on PPC. The following pattern is not supported: 7553// MemBarVolatile 7554// ^ ^ 7555// | | 7556// CtrlProj MemProj 7557// ^ ^ 7558// | | 7559// | Load 7560// | 7561// MemBarVolatile 7562// 7563// The first MemBarVolatile could get optimized out! According to 7564// Vladimir, this pattern can not occur on Oracle platforms. 7565// However, it does occur on PPC64 (because of membars in 7566// inline_unsafe_load_store). 7567// 7568// Add this node again if we found a good solution for inline_unsafe_load_store(). 7569// Don't forget to look at the implementation of post_store_load_barrier again, 7570// we did other fixes in that method. 7571//instruct unnecessary_membar_volatile() %{ 7572// match(MemBarVolatile); 7573// predicate(Matcher::post_store_load_barrier(n)); 7574// ins_cost(0); 7575// 7576// format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7577// size(0); 7578// ins_encode( /*empty*/ ); 7579// ins_pipe(pipe_class_default); 7580//%} 7581 7582instruct membar_CPUOrder() %{ 7583 match(MemBarCPUOrder); 7584 ins_cost(0); 7585 7586 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7587 size(0); 7588 ins_encode( /*empty*/ ); 7589 ins_pipe(pipe_class_default); 7590%} 7591 7592//----------Conditional Move--------------------------------------------------- 7593 7594// Cmove using isel. 7595instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7596 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7597 predicate(VM_Version::has_isel()); 7598 ins_cost(DEFAULT_COST); 7599 7600 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7601 size(4); 7602 ins_encode %{ 7603 // This is a Power7 instruction for which no machine description 7604 // exists. Anyways, the scheduler should be off on Power7. 7605 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7606 int cc = $cmp$$cmpcode; 7607 __ isel($dst$$Register, $crx$$CondRegister, 7608 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7609 %} 7610 ins_pipe(pipe_class_default); 7611%} 7612 7613instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7614 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7615 predicate(!VM_Version::has_isel()); 7616 ins_cost(DEFAULT_COST+BRANCH_COST); 7617 7618 ins_variable_size_depending_on_alignment(true); 7619 7620 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7621 // Worst case is branch + move + stop, no stop without scheduler 7622 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7623 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7624 ins_pipe(pipe_class_default); 7625%} 7626 7627instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7628 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7629 ins_cost(DEFAULT_COST+BRANCH_COST); 7630 7631 ins_variable_size_depending_on_alignment(true); 7632 7633 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7634 // Worst case is branch + move + stop, no stop without scheduler 7635 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7636 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7637 ins_pipe(pipe_class_default); 7638%} 7639 7640// Cmove using isel. 7641instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7642 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7643 predicate(VM_Version::has_isel()); 7644 ins_cost(DEFAULT_COST); 7645 7646 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7647 size(4); 7648 ins_encode %{ 7649 // This is a Power7 instruction for which no machine description 7650 // exists. Anyways, the scheduler should be off on Power7. 7651 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7652 int cc = $cmp$$cmpcode; 7653 __ isel($dst$$Register, $crx$$CondRegister, 7654 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7655 %} 7656 ins_pipe(pipe_class_default); 7657%} 7658 7659instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7660 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7661 predicate(!VM_Version::has_isel()); 7662 ins_cost(DEFAULT_COST+BRANCH_COST); 7663 7664 ins_variable_size_depending_on_alignment(true); 7665 7666 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7667 // Worst case is branch + move + stop, no stop without scheduler. 7668 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7669 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7670 ins_pipe(pipe_class_default); 7671%} 7672 7673instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7674 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7675 ins_cost(DEFAULT_COST+BRANCH_COST); 7676 7677 ins_variable_size_depending_on_alignment(true); 7678 7679 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7680 // Worst case is branch + move + stop, no stop without scheduler. 7681 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7682 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7683 ins_pipe(pipe_class_default); 7684%} 7685 7686// Cmove using isel. 7687instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7688 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7689 predicate(VM_Version::has_isel()); 7690 ins_cost(DEFAULT_COST); 7691 7692 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7693 size(4); 7694 ins_encode %{ 7695 // This is a Power7 instruction for which no machine description 7696 // exists. Anyways, the scheduler should be off on Power7. 7697 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7698 int cc = $cmp$$cmpcode; 7699 __ isel($dst$$Register, $crx$$CondRegister, 7700 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7701 %} 7702 ins_pipe(pipe_class_default); 7703%} 7704 7705// Conditional move for RegN. Only cmov(reg, reg). 7706instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7707 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7708 predicate(!VM_Version::has_isel()); 7709 ins_cost(DEFAULT_COST+BRANCH_COST); 7710 7711 ins_variable_size_depending_on_alignment(true); 7712 7713 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7714 // Worst case is branch + move + stop, no stop without scheduler. 7715 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7716 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7717 ins_pipe(pipe_class_default); 7718%} 7719 7720instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7721 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7722 ins_cost(DEFAULT_COST+BRANCH_COST); 7723 7724 ins_variable_size_depending_on_alignment(true); 7725 7726 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7727 // Worst case is branch + move + stop, no stop without scheduler. 7728 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7729 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7730 ins_pipe(pipe_class_default); 7731%} 7732 7733// Cmove using isel. 7734instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7735 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7736 predicate(VM_Version::has_isel()); 7737 ins_cost(DEFAULT_COST); 7738 7739 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7740 size(4); 7741 ins_encode %{ 7742 // This is a Power7 instruction for which no machine description 7743 // exists. Anyways, the scheduler should be off on Power7. 7744 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7745 int cc = $cmp$$cmpcode; 7746 __ isel($dst$$Register, $crx$$CondRegister, 7747 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7748 %} 7749 ins_pipe(pipe_class_default); 7750%} 7751 7752instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7753 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7754 predicate(!VM_Version::has_isel()); 7755 ins_cost(DEFAULT_COST+BRANCH_COST); 7756 7757 ins_variable_size_depending_on_alignment(true); 7758 7759 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7760 // Worst case is branch + move + stop, no stop without scheduler. 7761 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7762 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7763 ins_pipe(pipe_class_default); 7764%} 7765 7766instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7767 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7768 ins_cost(DEFAULT_COST+BRANCH_COST); 7769 7770 ins_variable_size_depending_on_alignment(true); 7771 7772 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7773 // Worst case is branch + move + stop, no stop without scheduler. 7774 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7775 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7776 ins_pipe(pipe_class_default); 7777%} 7778 7779instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7780 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7781 ins_cost(DEFAULT_COST+BRANCH_COST); 7782 7783 ins_variable_size_depending_on_alignment(true); 7784 7785 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7786 // Worst case is branch + move + stop, no stop without scheduler. 7787 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7788 ins_encode %{ 7789 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7790 Label done; 7791 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7792 // Branch if not (cmp crx). 7793 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7794 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7795 // TODO PPC port __ endgroup_if_needed(_size == 12); 7796 __ bind(done); 7797 %} 7798 ins_pipe(pipe_class_default); 7799%} 7800 7801instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7802 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7803 ins_cost(DEFAULT_COST+BRANCH_COST); 7804 7805 ins_variable_size_depending_on_alignment(true); 7806 7807 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7808 // Worst case is branch + move + stop, no stop without scheduler. 7809 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7810 ins_encode %{ 7811 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7812 Label done; 7813 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7814 // Branch if not (cmp crx). 7815 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7816 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7817 // TODO PPC port __ endgroup_if_needed(_size == 12); 7818 __ bind(done); 7819 %} 7820 ins_pipe(pipe_class_default); 7821%} 7822 7823//----------Conditional_store-------------------------------------------------- 7824// Conditional-store of the updated heap-top. 7825// Used during allocation of the shared heap. 7826// Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7827 7828// As compareAndSwapL, but return flag register instead of boolean value in 7829// int register. 7830// Used by sun/misc/AtomicLongCSImpl.java. 7831// Mem_ptr must be a memory operand, else this node does not get 7832// Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7833// can be rematerialized which leads to errors. 7834instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7835 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7836 effect(TEMP cr0); 7837 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7838 ins_encode %{ 7839 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7840 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7841 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7842 noreg, NULL, true); 7843 %} 7844 ins_pipe(pipe_class_default); 7845%} 7846 7847// As compareAndSwapP, but return flag register instead of boolean value in 7848// int register. 7849// This instruction is matched if UseTLAB is off. 7850// Mem_ptr must be a memory operand, else this node does not get 7851// Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7852// can be rematerialized which leads to errors. 7853instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7854 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7855 ins_cost(2*MEMORY_REF_COST); 7856 7857 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7858 ins_encode %{ 7859 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7860 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7861 %} 7862 ins_pipe(pipe_class_memory); 7863%} 7864 7865// Implement LoadPLocked. Must be ordered against changes of the memory location 7866// by storePConditional. 7867// Don't know whether this is ever used. 7868instruct loadPLocked(iRegPdst dst, memory mem) %{ 7869 match(Set dst (LoadPLocked mem)); 7870 ins_cost(2*MEMORY_REF_COST); 7871 7872 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7873 size(4); 7874 ins_encode %{ 7875 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7876 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7877 %} 7878 ins_pipe(pipe_class_memory); 7879%} 7880 7881//----------Compare-And-Swap--------------------------------------------------- 7882 7883// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7884// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7885// matched. 7886 7887// Strong versions: 7888 7889instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7890 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7891 predicate(VM_Version::has_lqarx()); 7892 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7893 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7894 ins_encode %{ 7895 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7896 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7897 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7898 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7899 $res$$Register, true); 7900 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7901 __ isync(); 7902 } else { 7903 __ sync(); 7904 } 7905 %} 7906 ins_pipe(pipe_class_default); 7907%} 7908 7909instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7910 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7911 predicate(!VM_Version::has_lqarx()); 7912 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7913 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7914 ins_encode %{ 7915 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7916 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7917 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7918 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7919 $res$$Register, true); 7920 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7921 __ isync(); 7922 } else { 7923 __ sync(); 7924 } 7925 %} 7926 ins_pipe(pipe_class_default); 7927%} 7928 7929instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7930 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7931 predicate(VM_Version::has_lqarx()); 7932 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7933 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7934 ins_encode %{ 7935 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7936 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7937 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7938 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7939 $res$$Register, true); 7940 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7941 __ isync(); 7942 } else { 7943 __ sync(); 7944 } 7945 %} 7946 ins_pipe(pipe_class_default); 7947%} 7948 7949instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7950 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7951 predicate(!VM_Version::has_lqarx()); 7952 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7953 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7954 ins_encode %{ 7955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7956 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7957 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7958 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7959 $res$$Register, true); 7960 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7961 __ isync(); 7962 } else { 7963 __ sync(); 7964 } 7965 %} 7966 ins_pipe(pipe_class_default); 7967%} 7968 7969instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7970 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7971 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7972 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7973 ins_encode %{ 7974 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7975 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7976 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7977 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7978 $res$$Register, true); 7979 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7980 __ isync(); 7981 } else { 7982 __ sync(); 7983 } 7984 %} 7985 ins_pipe(pipe_class_default); 7986%} 7987 7988instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7989 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7990 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7991 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7992 ins_encode %{ 7993 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7994 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7995 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7996 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7997 $res$$Register, true); 7998 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7999 __ isync(); 8000 } else { 8001 __ sync(); 8002 } 8003 %} 8004 ins_pipe(pipe_class_default); 8005%} 8006 8007instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8008 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 8009 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8010 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8011 ins_encode %{ 8012 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8013 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8014 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8015 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8016 $res$$Register, NULL, true); 8017 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8018 __ isync(); 8019 } else { 8020 __ sync(); 8021 } 8022 %} 8023 ins_pipe(pipe_class_default); 8024%} 8025 8026instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8027 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 8028 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8029 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8030 ins_encode %{ 8031 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8032 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8033 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8034 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8035 $res$$Register, NULL, true); 8036 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8037 __ isync(); 8038 } else { 8039 __ sync(); 8040 } 8041 %} 8042 ins_pipe(pipe_class_default); 8043%} 8044 8045// Weak versions: 8046 8047instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8048 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8049 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8050 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8051 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8052 ins_encode %{ 8053 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8054 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8055 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8056 MacroAssembler::MemBarNone, 8057 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8058 %} 8059 ins_pipe(pipe_class_default); 8060%} 8061 8062instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8063 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8064 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8065 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8066 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 8067 ins_encode %{ 8068 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8069 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8070 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8071 MacroAssembler::MemBarNone, 8072 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8073 %} 8074 ins_pipe(pipe_class_default); 8075%} 8076 8077instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8078 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8079 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8080 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8081 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8082 ins_encode %{ 8083 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8084 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8085 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8086 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8087 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8088 %} 8089 ins_pipe(pipe_class_default); 8090%} 8091 8092instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8093 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 8094 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8095 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8096 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 8097 ins_encode %{ 8098 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8099 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8100 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8101 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8102 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8103 %} 8104 ins_pipe(pipe_class_default); 8105%} 8106 8107instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8108 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8109 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8110 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8111 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8112 ins_encode %{ 8113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8115 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8116 MacroAssembler::MemBarNone, 8117 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8118 %} 8119 ins_pipe(pipe_class_default); 8120%} 8121 8122instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8123 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8124 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8125 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8126 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 8127 ins_encode %{ 8128 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8129 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8130 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8131 MacroAssembler::MemBarNone, 8132 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8133 %} 8134 ins_pipe(pipe_class_default); 8135%} 8136 8137instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8138 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8139 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8140 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8141 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8142 ins_encode %{ 8143 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8144 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8145 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8146 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8147 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8148 %} 8149 ins_pipe(pipe_class_default); 8150%} 8151 8152instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 8153 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 8154 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8155 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 8156 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 8157 ins_encode %{ 8158 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8159 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8160 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 8161 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8162 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8163 %} 8164 ins_pipe(pipe_class_default); 8165%} 8166 8167instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8168 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8169 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8170 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8171 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8172 ins_encode %{ 8173 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8174 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8175 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8176 MacroAssembler::MemBarNone, 8177 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8178 %} 8179 ins_pipe(pipe_class_default); 8180%} 8181 8182instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8183 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 8184 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8185 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8186 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8187 ins_encode %{ 8188 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8189 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8190 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8191 // value is never passed to caller. 8192 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8193 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8194 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8195 %} 8196 ins_pipe(pipe_class_default); 8197%} 8198 8199instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8200 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8201 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8202 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8203 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 8204 ins_encode %{ 8205 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8206 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8207 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8208 MacroAssembler::MemBarNone, 8209 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8210 %} 8211 ins_pipe(pipe_class_default); 8212%} 8213 8214instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8215 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 8216 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8217 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8218 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 8219 ins_encode %{ 8220 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8221 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8222 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8223 // value is never passed to caller. 8224 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8225 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8226 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 8227 %} 8228 ins_pipe(pipe_class_default); 8229%} 8230 8231instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8232 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8233 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8234 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8235 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 8236 ins_encode %{ 8237 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8238 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8239 // value is never passed to caller. 8240 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8241 MacroAssembler::MemBarNone, 8242 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8243 %} 8244 ins_pipe(pipe_class_default); 8245%} 8246 8247instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8248 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 8249 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8250 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8251 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 8252 ins_encode %{ 8253 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8254 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8255 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8256 // value is never passed to caller. 8257 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8258 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8259 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8260 %} 8261 ins_pipe(pipe_class_default); 8262%} 8263 8264instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8265 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8266 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8267 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8268 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8269 ins_encode %{ 8270 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8271 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8272 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8273 MacroAssembler::MemBarNone, 8274 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8275 %} 8276 ins_pipe(pipe_class_default); 8277%} 8278 8279instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8280 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 8281 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8282 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 8283 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 8284 ins_encode %{ 8285 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8286 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8287 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 8288 // value is never passed to caller. 8289 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8290 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 8291 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 8292 %} 8293 ins_pipe(pipe_class_default); 8294%} 8295 8296// CompareAndExchange 8297 8298instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8299 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8300 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8301 effect(TEMP_DEF res, TEMP cr0); 8302 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8303 ins_encode %{ 8304 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8305 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8306 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8307 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8308 noreg, true); 8309 %} 8310 ins_pipe(pipe_class_default); 8311%} 8312 8313instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8314 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8315 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8316 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8317 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 8318 ins_encode %{ 8319 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8320 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8321 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8322 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8323 noreg, true); 8324 %} 8325 ins_pipe(pipe_class_default); 8326%} 8327 8328instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8329 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8330 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8331 effect(TEMP_DEF res, TEMP cr0); 8332 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8333 ins_encode %{ 8334 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8335 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8336 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8337 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8338 noreg, true); 8339 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8340 __ isync(); 8341 } else { 8342 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8343 __ sync(); 8344 } 8345 %} 8346 ins_pipe(pipe_class_default); 8347%} 8348 8349instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8350 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 8351 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8352 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8353 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 8354 ins_encode %{ 8355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8356 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8357 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8358 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8359 noreg, true); 8360 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8361 __ isync(); 8362 } else { 8363 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8364 __ sync(); 8365 } 8366 %} 8367 ins_pipe(pipe_class_default); 8368%} 8369 8370instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8371 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8372 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 8373 effect(TEMP_DEF res, TEMP cr0); 8374 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8375 ins_encode %{ 8376 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8377 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8378 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8379 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8380 noreg, true); 8381 %} 8382 ins_pipe(pipe_class_default); 8383%} 8384 8385instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8386 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8387 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 8388 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8389 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8392 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8393 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8394 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8395 noreg, true); 8396 %} 8397 ins_pipe(pipe_class_default); 8398%} 8399 8400instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8401 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8402 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8403 effect(TEMP_DEF res, TEMP cr0); 8404 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8405 ins_encode %{ 8406 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8407 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8408 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8409 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8410 noreg, true); 8411 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8412 __ isync(); 8413 } else { 8414 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8415 __ sync(); 8416 } 8417 %} 8418 ins_pipe(pipe_class_default); 8419%} 8420 8421instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8422 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8423 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8424 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8425 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8426 ins_encode %{ 8427 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8428 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8429 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8430 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8431 noreg, true); 8432 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8433 __ isync(); 8434 } else { 8435 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8436 __ sync(); 8437 } 8438 %} 8439 ins_pipe(pipe_class_default); 8440%} 8441 8442instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8443 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8444 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8445 effect(TEMP_DEF res, TEMP cr0); 8446 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8447 ins_encode %{ 8448 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8449 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8450 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8451 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8452 noreg, true); 8453 %} 8454 ins_pipe(pipe_class_default); 8455%} 8456 8457instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8458 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8459 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8460 effect(TEMP_DEF res, TEMP cr0); 8461 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8462 ins_encode %{ 8463 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8464 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8465 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8466 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8467 noreg, true); 8468 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8469 __ isync(); 8470 } else { 8471 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8472 __ sync(); 8473 } 8474 %} 8475 ins_pipe(pipe_class_default); 8476%} 8477 8478instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8479 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8480 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8481 effect(TEMP_DEF res, TEMP cr0); 8482 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8483 ins_encode %{ 8484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8485 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8486 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8487 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8488 noreg, true); 8489 %} 8490 ins_pipe(pipe_class_default); 8491%} 8492 8493instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8494 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8495 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8496 effect(TEMP_DEF res, TEMP cr0); 8497 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8498 ins_encode %{ 8499 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8500 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8501 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8502 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8503 noreg, true); 8504 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8505 __ isync(); 8506 } else { 8507 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8508 __ sync(); 8509 } 8510 %} 8511 ins_pipe(pipe_class_default); 8512%} 8513 8514instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8515 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8516 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8517 effect(TEMP_DEF res, TEMP cr0); 8518 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8519 ins_encode %{ 8520 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8521 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8522 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8523 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8524 noreg, NULL, true); 8525 %} 8526 ins_pipe(pipe_class_default); 8527%} 8528 8529instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8530 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8531 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8532 effect(TEMP_DEF res, TEMP cr0); 8533 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8534 ins_encode %{ 8535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8537 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8539 noreg, NULL, true); 8540 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8541 __ isync(); 8542 } else { 8543 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8544 __ sync(); 8545 } 8546 %} 8547 ins_pipe(pipe_class_default); 8548%} 8549 8550instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8551 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8552 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8553 effect(TEMP_DEF res, TEMP cr0); 8554 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8555 ins_encode %{ 8556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8557 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8558 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8559 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8560 noreg, NULL, true); 8561 %} 8562 ins_pipe(pipe_class_default); 8563%} 8564 8565instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8566 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8567 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8568 effect(TEMP_DEF res, TEMP cr0); 8569 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8570 ins_encode %{ 8571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8573 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8575 noreg, NULL, true); 8576 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8577 __ isync(); 8578 } else { 8579 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8580 __ sync(); 8581 } 8582 %} 8583 ins_pipe(pipe_class_default); 8584%} 8585 8586// Special RMW 8587 8588instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8589 match(Set res (GetAndAddB mem_ptr src)); 8590 predicate(VM_Version::has_lqarx()); 8591 effect(TEMP_DEF res, TEMP cr0); 8592 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8593 ins_encode %{ 8594 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8595 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8596 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8597 __ isync(); 8598 } else { 8599 __ sync(); 8600 } 8601 %} 8602 ins_pipe(pipe_class_default); 8603%} 8604 8605instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8606 match(Set res (GetAndAddB mem_ptr src)); 8607 predicate(!VM_Version::has_lqarx()); 8608 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8609 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8610 ins_encode %{ 8611 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8612 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8613 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8614 __ isync(); 8615 } else { 8616 __ sync(); 8617 } 8618 %} 8619 ins_pipe(pipe_class_default); 8620%} 8621 8622instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8623 match(Set res (GetAndAddS mem_ptr src)); 8624 predicate(VM_Version::has_lqarx()); 8625 effect(TEMP_DEF res, TEMP cr0); 8626 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8627 ins_encode %{ 8628 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8629 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8630 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8631 __ isync(); 8632 } else { 8633 __ sync(); 8634 } 8635 %} 8636 ins_pipe(pipe_class_default); 8637%} 8638 8639instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8640 match(Set res (GetAndAddS mem_ptr src)); 8641 predicate(!VM_Version::has_lqarx()); 8642 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8643 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8644 ins_encode %{ 8645 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8646 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8647 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8648 __ isync(); 8649 } else { 8650 __ sync(); 8651 } 8652 %} 8653 ins_pipe(pipe_class_default); 8654%} 8655 8656instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8657 match(Set res (GetAndAddI mem_ptr src)); 8658 effect(TEMP_DEF res, TEMP cr0); 8659 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8660 ins_encode %{ 8661 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8662 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8663 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8664 __ isync(); 8665 } else { 8666 __ sync(); 8667 } 8668 %} 8669 ins_pipe(pipe_class_default); 8670%} 8671 8672instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8673 match(Set res (GetAndAddL mem_ptr src)); 8674 effect(TEMP_DEF res, TEMP cr0); 8675 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8676 ins_encode %{ 8677 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8678 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8679 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8680 __ isync(); 8681 } else { 8682 __ sync(); 8683 } 8684 %} 8685 ins_pipe(pipe_class_default); 8686%} 8687 8688instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8689 match(Set res (GetAndSetB mem_ptr src)); 8690 predicate(VM_Version::has_lqarx()); 8691 effect(TEMP_DEF res, TEMP cr0); 8692 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8693 ins_encode %{ 8694 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8695 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8696 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8697 __ isync(); 8698 } else { 8699 __ sync(); 8700 } 8701 %} 8702 ins_pipe(pipe_class_default); 8703%} 8704 8705instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8706 match(Set res (GetAndSetB mem_ptr src)); 8707 predicate(!VM_Version::has_lqarx()); 8708 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8709 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8710 ins_encode %{ 8711 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8712 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8713 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8714 __ isync(); 8715 } else { 8716 __ sync(); 8717 } 8718 %} 8719 ins_pipe(pipe_class_default); 8720%} 8721 8722instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8723 match(Set res (GetAndSetS mem_ptr src)); 8724 predicate(VM_Version::has_lqarx()); 8725 effect(TEMP_DEF res, TEMP cr0); 8726 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8727 ins_encode %{ 8728 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8729 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8730 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8731 __ isync(); 8732 } else { 8733 __ sync(); 8734 } 8735 %} 8736 ins_pipe(pipe_class_default); 8737%} 8738 8739instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8740 match(Set res (GetAndSetS mem_ptr src)); 8741 predicate(!VM_Version::has_lqarx()); 8742 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8743 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8744 ins_encode %{ 8745 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8746 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8747 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8748 __ isync(); 8749 } else { 8750 __ sync(); 8751 } 8752 %} 8753 ins_pipe(pipe_class_default); 8754%} 8755 8756instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8757 match(Set res (GetAndSetI mem_ptr src)); 8758 effect(TEMP_DEF res, TEMP cr0); 8759 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8760 ins_encode %{ 8761 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8762 MacroAssembler::cmpxchgx_hint_atomic_update()); 8763 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8764 __ isync(); 8765 } else { 8766 __ sync(); 8767 } 8768 %} 8769 ins_pipe(pipe_class_default); 8770%} 8771 8772instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8773 match(Set res (GetAndSetL mem_ptr src)); 8774 effect(TEMP_DEF res, TEMP cr0); 8775 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8776 ins_encode %{ 8777 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8778 MacroAssembler::cmpxchgx_hint_atomic_update()); 8779 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8780 __ isync(); 8781 } else { 8782 __ sync(); 8783 } 8784 %} 8785 ins_pipe(pipe_class_default); 8786%} 8787 8788instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8789 match(Set res (GetAndSetP mem_ptr src)); 8790 effect(TEMP_DEF res, TEMP cr0); 8791 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8792 ins_encode %{ 8793 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8794 MacroAssembler::cmpxchgx_hint_atomic_update()); 8795 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8796 __ isync(); 8797 } else { 8798 __ sync(); 8799 } 8800 %} 8801 ins_pipe(pipe_class_default); 8802%} 8803 8804instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8805 match(Set res (GetAndSetN mem_ptr src)); 8806 effect(TEMP_DEF res, TEMP cr0); 8807 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8808 ins_encode %{ 8809 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8810 MacroAssembler::cmpxchgx_hint_atomic_update()); 8811 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8812 __ isync(); 8813 } else { 8814 __ sync(); 8815 } 8816 %} 8817 ins_pipe(pipe_class_default); 8818%} 8819 8820//----------Arithmetic Instructions-------------------------------------------- 8821// Addition Instructions 8822 8823// Register Addition 8824instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8825 match(Set dst (AddI src1 src2)); 8826 format %{ "ADD $dst, $src1, $src2" %} 8827 size(4); 8828 ins_encode %{ 8829 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8830 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8831 %} 8832 ins_pipe(pipe_class_default); 8833%} 8834 8835// Expand does not work with above instruct. (??) 8836instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8837 // no match-rule 8838 effect(DEF dst, USE src1, USE src2); 8839 format %{ "ADD $dst, $src1, $src2" %} 8840 size(4); 8841 ins_encode %{ 8842 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8843 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8844 %} 8845 ins_pipe(pipe_class_default); 8846%} 8847 8848instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8849 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8850 ins_cost(DEFAULT_COST*3); 8851 8852 expand %{ 8853 // FIXME: we should do this in the ideal world. 8854 iRegIdst tmp1; 8855 iRegIdst tmp2; 8856 addI_reg_reg(tmp1, src1, src2); 8857 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8858 addI_reg_reg(dst, tmp1, tmp2); 8859 %} 8860%} 8861 8862// Immediate Addition 8863instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8864 match(Set dst (AddI src1 src2)); 8865 format %{ "ADDI $dst, $src1, $src2" %} 8866 size(4); 8867 ins_encode %{ 8868 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8869 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8870 %} 8871 ins_pipe(pipe_class_default); 8872%} 8873 8874// Immediate Addition with 16-bit shifted operand 8875instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8876 match(Set dst (AddI src1 src2)); 8877 format %{ "ADDIS $dst, $src1, $src2" %} 8878 size(4); 8879 ins_encode %{ 8880 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8881 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8882 %} 8883 ins_pipe(pipe_class_default); 8884%} 8885 8886// Long Addition 8887instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8888 match(Set dst (AddL src1 src2)); 8889 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8890 size(4); 8891 ins_encode %{ 8892 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8893 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8894 %} 8895 ins_pipe(pipe_class_default); 8896%} 8897 8898// Expand does not work with above instruct. (??) 8899instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8900 // no match-rule 8901 effect(DEF dst, USE src1, USE src2); 8902 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8903 size(4); 8904 ins_encode %{ 8905 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8906 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8907 %} 8908 ins_pipe(pipe_class_default); 8909%} 8910 8911instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8912 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8913 ins_cost(DEFAULT_COST*3); 8914 8915 expand %{ 8916 // FIXME: we should do this in the ideal world. 8917 iRegLdst tmp1; 8918 iRegLdst tmp2; 8919 addL_reg_reg(tmp1, src1, src2); 8920 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8921 addL_reg_reg(dst, tmp1, tmp2); 8922 %} 8923%} 8924 8925// AddL + ConvL2I. 8926instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8927 match(Set dst (ConvL2I (AddL src1 src2))); 8928 8929 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8930 size(4); 8931 ins_encode %{ 8932 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8933 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8934 %} 8935 ins_pipe(pipe_class_default); 8936%} 8937 8938// No constant pool entries required. 8939instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8940 match(Set dst (AddL src1 src2)); 8941 8942 format %{ "ADDI $dst, $src1, $src2" %} 8943 size(4); 8944 ins_encode %{ 8945 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8946 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8947 %} 8948 ins_pipe(pipe_class_default); 8949%} 8950 8951// Long Immediate Addition with 16-bit shifted operand. 8952// No constant pool entries required. 8953instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8954 match(Set dst (AddL src1 src2)); 8955 8956 format %{ "ADDIS $dst, $src1, $src2" %} 8957 size(4); 8958 ins_encode %{ 8959 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8960 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8961 %} 8962 ins_pipe(pipe_class_default); 8963%} 8964 8965// Pointer Register Addition 8966instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8967 match(Set dst (AddP src1 src2)); 8968 format %{ "ADD $dst, $src1, $src2" %} 8969 size(4); 8970 ins_encode %{ 8971 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8972 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8973 %} 8974 ins_pipe(pipe_class_default); 8975%} 8976 8977// Pointer Immediate Addition 8978// No constant pool entries required. 8979instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8980 match(Set dst (AddP src1 src2)); 8981 8982 format %{ "ADDI $dst, $src1, $src2" %} 8983 size(4); 8984 ins_encode %{ 8985 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8986 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8987 %} 8988 ins_pipe(pipe_class_default); 8989%} 8990 8991// Pointer Immediate Addition with 16-bit shifted operand. 8992// No constant pool entries required. 8993instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8994 match(Set dst (AddP src1 src2)); 8995 8996 format %{ "ADDIS $dst, $src1, $src2" %} 8997 size(4); 8998 ins_encode %{ 8999 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 9000 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 9001 %} 9002 ins_pipe(pipe_class_default); 9003%} 9004 9005//--------------------- 9006// Subtraction Instructions 9007 9008// Register Subtraction 9009instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9010 match(Set dst (SubI src1 src2)); 9011 format %{ "SUBF $dst, $src2, $src1" %} 9012 size(4); 9013 ins_encode %{ 9014 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9015 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9016 %} 9017 ins_pipe(pipe_class_default); 9018%} 9019 9020// Immediate Subtraction 9021// Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 9022// Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 9023 9024// SubI from constant (using subfic). 9025instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 9026 match(Set dst (SubI src1 src2)); 9027 format %{ "SUBI $dst, $src1, $src2" %} 9028 9029 size(4); 9030 ins_encode %{ 9031 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 9032 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 9033 %} 9034 ins_pipe(pipe_class_default); 9035%} 9036 9037// Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 9038// positive integers and 0xF...F for negative ones. 9039instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 9040 // no match-rule, false predicate 9041 effect(DEF dst, USE src); 9042 predicate(false); 9043 9044 format %{ "SRAWI $dst, $src, #31" %} 9045 size(4); 9046 ins_encode %{ 9047 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9048 __ srawi($dst$$Register, $src$$Register, 0x1f); 9049 %} 9050 ins_pipe(pipe_class_default); 9051%} 9052 9053instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 9054 match(Set dst (AbsI src)); 9055 ins_cost(DEFAULT_COST*3); 9056 9057 expand %{ 9058 iRegIdst tmp1; 9059 iRegIdst tmp2; 9060 signmask32I_regI(tmp1, src); 9061 xorI_reg_reg(tmp2, tmp1, src); 9062 subI_reg_reg(dst, tmp2, tmp1); 9063 %} 9064%} 9065 9066instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 9067 match(Set dst (SubI zero src2)); 9068 format %{ "NEG $dst, $src2" %} 9069 size(4); 9070 ins_encode %{ 9071 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9072 __ neg($dst$$Register, $src2$$Register); 9073 %} 9074 ins_pipe(pipe_class_default); 9075%} 9076 9077// Long subtraction 9078instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9079 match(Set dst (SubL src1 src2)); 9080 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 9081 size(4); 9082 ins_encode %{ 9083 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9084 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9085 %} 9086 ins_pipe(pipe_class_default); 9087%} 9088 9089// SubL + convL2I. 9090instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9091 match(Set dst (ConvL2I (SubL src1 src2))); 9092 9093 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 9094 size(4); 9095 ins_encode %{ 9096 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 9097 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 9098 %} 9099 ins_pipe(pipe_class_default); 9100%} 9101 9102// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9103// positive longs and 0xF...F for negative ones. 9104instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 9105 // no match-rule, false predicate 9106 effect(DEF dst, USE src); 9107 predicate(false); 9108 9109 format %{ "SRADI $dst, $src, #63" %} 9110 size(4); 9111 ins_encode %{ 9112 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9113 __ sradi($dst$$Register, $src$$Register, 0x3f); 9114 %} 9115 ins_pipe(pipe_class_default); 9116%} 9117 9118// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 9119// positive longs and 0xF...F for negative ones. 9120instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 9121 // no match-rule, false predicate 9122 effect(DEF dst, USE src); 9123 predicate(false); 9124 9125 format %{ "SRADI $dst, $src, #63" %} 9126 size(4); 9127 ins_encode %{ 9128 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9129 __ sradi($dst$$Register, $src$$Register, 0x3f); 9130 %} 9131 ins_pipe(pipe_class_default); 9132%} 9133 9134// Long negation 9135instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 9136 match(Set dst (SubL zero src2)); 9137 format %{ "NEG $dst, $src2 \t// long" %} 9138 size(4); 9139 ins_encode %{ 9140 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9141 __ neg($dst$$Register, $src2$$Register); 9142 %} 9143 ins_pipe(pipe_class_default); 9144%} 9145 9146// NegL + ConvL2I. 9147instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 9148 match(Set dst (ConvL2I (SubL zero src2))); 9149 9150 format %{ "NEG $dst, $src2 \t// long + l2i" %} 9151 size(4); 9152 ins_encode %{ 9153 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9154 __ neg($dst$$Register, $src2$$Register); 9155 %} 9156 ins_pipe(pipe_class_default); 9157%} 9158 9159// Multiplication Instructions 9160// Integer Multiplication 9161 9162// Register Multiplication 9163instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9164 match(Set dst (MulI src1 src2)); 9165 ins_cost(DEFAULT_COST); 9166 9167 format %{ "MULLW $dst, $src1, $src2" %} 9168 size(4); 9169 ins_encode %{ 9170 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 9171 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 9172 %} 9173 ins_pipe(pipe_class_default); 9174%} 9175 9176// Immediate Multiplication 9177instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 9178 match(Set dst (MulI src1 src2)); 9179 ins_cost(DEFAULT_COST); 9180 9181 format %{ "MULLI $dst, $src1, $src2" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9185 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9186 %} 9187 ins_pipe(pipe_class_default); 9188%} 9189 9190instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9191 match(Set dst (MulL src1 src2)); 9192 ins_cost(DEFAULT_COST); 9193 9194 format %{ "MULLD $dst $src1, $src2 \t// long" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 9198 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 9199 %} 9200 ins_pipe(pipe_class_default); 9201%} 9202 9203// Multiply high for optimized long division by constant. 9204instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9205 match(Set dst (MulHiL src1 src2)); 9206 ins_cost(DEFAULT_COST); 9207 9208 format %{ "MULHD $dst $src1, $src2 \t// long" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 9212 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 9213 %} 9214 ins_pipe(pipe_class_default); 9215%} 9216 9217// Immediate Multiplication 9218instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 9219 match(Set dst (MulL src1 src2)); 9220 ins_cost(DEFAULT_COST); 9221 9222 format %{ "MULLI $dst, $src1, $src2" %} 9223 size(4); 9224 ins_encode %{ 9225 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 9226 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 9227 %} 9228 ins_pipe(pipe_class_default); 9229%} 9230 9231// Integer Division with Immediate -1: Negate. 9232instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9233 match(Set dst (DivI src1 src2)); 9234 ins_cost(DEFAULT_COST); 9235 9236 format %{ "NEG $dst, $src1 \t// /-1" %} 9237 size(4); 9238 ins_encode %{ 9239 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9240 __ neg($dst$$Register, $src1$$Register); 9241 %} 9242 ins_pipe(pipe_class_default); 9243%} 9244 9245// Integer Division with constant, but not -1. 9246// We should be able to improve this by checking the type of src2. 9247// It might well be that src2 is known to be positive. 9248instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9249 match(Set dst (DivI src1 src2)); 9250 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 9251 ins_cost(2*DEFAULT_COST); 9252 9253 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 9254 size(4); 9255 ins_encode %{ 9256 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 9257 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 9258 %} 9259 ins_pipe(pipe_class_default); 9260%} 9261 9262instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 9263 effect(USE_DEF dst, USE src1, USE crx); 9264 predicate(false); 9265 9266 ins_variable_size_depending_on_alignment(true); 9267 9268 format %{ "CMOVE $dst, neg($src1), $crx" %} 9269 // Worst case is branch + move + stop, no stop without scheduler. 9270 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9271 ins_encode %{ 9272 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9273 Label done; 9274 __ bne($crx$$CondRegister, done); 9275 __ neg($dst$$Register, $src1$$Register); 9276 // TODO PPC port __ endgroup_if_needed(_size == 12); 9277 __ bind(done); 9278 %} 9279 ins_pipe(pipe_class_default); 9280%} 9281 9282// Integer Division with Registers not containing constants. 9283instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9284 match(Set dst (DivI src1 src2)); 9285 ins_cost(10*DEFAULT_COST); 9286 9287 expand %{ 9288 immI16 imm %{ (int)-1 %} 9289 flagsReg tmp1; 9290 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9291 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9292 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9293 %} 9294%} 9295 9296// Long Division with Immediate -1: Negate. 9297instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9298 match(Set dst (DivL src1 src2)); 9299 ins_cost(DEFAULT_COST); 9300 9301 format %{ "NEG $dst, $src1 \t// /-1, long" %} 9302 size(4); 9303 ins_encode %{ 9304 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 9305 __ neg($dst$$Register, $src1$$Register); 9306 %} 9307 ins_pipe(pipe_class_default); 9308%} 9309 9310// Long Division with constant, but not -1. 9311instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9312 match(Set dst (DivL src1 src2)); 9313 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 9314 ins_cost(2*DEFAULT_COST); 9315 9316 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 9317 size(4); 9318 ins_encode %{ 9319 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 9320 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 9321 %} 9322 ins_pipe(pipe_class_default); 9323%} 9324 9325instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 9326 effect(USE_DEF dst, USE src1, USE crx); 9327 predicate(false); 9328 9329 ins_variable_size_depending_on_alignment(true); 9330 9331 format %{ "CMOVE $dst, neg($src1), $crx" %} 9332 // Worst case is branch + move + stop, no stop without scheduler. 9333 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 9334 ins_encode %{ 9335 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 9336 Label done; 9337 __ bne($crx$$CondRegister, done); 9338 __ neg($dst$$Register, $src1$$Register); 9339 // TODO PPC port __ endgroup_if_needed(_size == 12); 9340 __ bind(done); 9341 %} 9342 ins_pipe(pipe_class_default); 9343%} 9344 9345// Long Division with Registers not containing constants. 9346instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9347 match(Set dst (DivL src1 src2)); 9348 ins_cost(10*DEFAULT_COST); 9349 9350 expand %{ 9351 immL16 imm %{ (int)-1 %} 9352 flagsReg tmp1; 9353 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9354 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 9355 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 9356 %} 9357%} 9358 9359// Integer Remainder with registers. 9360instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9361 match(Set dst (ModI src1 src2)); 9362 ins_cost(10*DEFAULT_COST); 9363 9364 expand %{ 9365 immI16 imm %{ (int)-1 %} 9366 flagsReg tmp1; 9367 iRegIdst tmp2; 9368 iRegIdst tmp3; 9369 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 9370 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9371 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9372 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9373 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9374 %} 9375%} 9376 9377// Long Remainder with registers 9378instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9379 match(Set dst (ModL src1 src2)); 9380 ins_cost(10*DEFAULT_COST); 9381 9382 expand %{ 9383 immL16 imm %{ (int)-1 %} 9384 flagsReg tmp1; 9385 iRegLdst tmp2; 9386 iRegLdst tmp3; 9387 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 9388 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 9389 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 9390 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 9391 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 9392 %} 9393%} 9394 9395// Integer Shift Instructions 9396 9397// Register Shift Left 9398 9399// Clear all but the lowest #mask bits. 9400// Used to normalize shift amounts in registers. 9401instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9402 // no match-rule, false predicate 9403 effect(DEF dst, USE src, USE mask); 9404 predicate(false); 9405 9406 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9407 size(4); 9408 ins_encode %{ 9409 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9410 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9411 %} 9412 ins_pipe(pipe_class_default); 9413%} 9414 9415instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9416 // no match-rule, false predicate 9417 effect(DEF dst, USE src1, USE src2); 9418 predicate(false); 9419 9420 format %{ "SLW $dst, $src1, $src2" %} 9421 size(4); 9422 ins_encode %{ 9423 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9424 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9425 %} 9426 ins_pipe(pipe_class_default); 9427%} 9428 9429instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9430 match(Set dst (LShiftI src1 src2)); 9431 ins_cost(DEFAULT_COST*2); 9432 expand %{ 9433 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9434 iRegIdst tmpI; 9435 maskI_reg_imm(tmpI, src2, mask); 9436 lShiftI_reg_reg(dst, src1, tmpI); 9437 %} 9438%} 9439 9440// Register Shift Left Immediate 9441instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9442 match(Set dst (LShiftI src1 src2)); 9443 9444 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9445 size(4); 9446 ins_encode %{ 9447 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9448 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9449 %} 9450 ins_pipe(pipe_class_default); 9451%} 9452 9453// AndI with negpow2-constant + LShiftI 9454instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9455 match(Set dst (LShiftI (AndI src1 src2) src3)); 9456 predicate(UseRotateAndMaskInstructionsPPC64); 9457 9458 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9459 size(4); 9460 ins_encode %{ 9461 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9462 long src2 = $src2$$constant; 9463 long src3 = $src3$$constant; 9464 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9465 if (maskbits >= 32) { 9466 __ li($dst$$Register, 0); // addi 9467 } else { 9468 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9469 } 9470 %} 9471 ins_pipe(pipe_class_default); 9472%} 9473 9474// RShiftI + AndI with negpow2-constant + LShiftI 9475instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9476 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9477 predicate(UseRotateAndMaskInstructionsPPC64); 9478 9479 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9480 size(4); 9481 ins_encode %{ 9482 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9483 long src2 = $src2$$constant; 9484 long src3 = $src3$$constant; 9485 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9486 if (maskbits >= 32) { 9487 __ li($dst$$Register, 0); // addi 9488 } else { 9489 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9490 } 9491 %} 9492 ins_pipe(pipe_class_default); 9493%} 9494 9495instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9496 // no match-rule, false predicate 9497 effect(DEF dst, USE src1, USE src2); 9498 predicate(false); 9499 9500 format %{ "SLD $dst, $src1, $src2" %} 9501 size(4); 9502 ins_encode %{ 9503 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9504 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9505 %} 9506 ins_pipe(pipe_class_default); 9507%} 9508 9509// Register Shift Left 9510instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9511 match(Set dst (LShiftL src1 src2)); 9512 ins_cost(DEFAULT_COST*2); 9513 expand %{ 9514 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9515 iRegIdst tmpI; 9516 maskI_reg_imm(tmpI, src2, mask); 9517 lShiftL_regL_regI(dst, src1, tmpI); 9518 %} 9519%} 9520 9521// Register Shift Left Immediate 9522instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9523 match(Set dst (LShiftL src1 src2)); 9524 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9525 size(4); 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// If we shift more than 32 bits, we need not convert I2L. 9534instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9535 match(Set dst (LShiftL (ConvI2L src1) src2)); 9536 ins_cost(DEFAULT_COST); 9537 9538 size(4); 9539 format %{ "SLDI $dst, i2l($src1), $src2" %} 9540 ins_encode %{ 9541 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9542 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9543 %} 9544 ins_pipe(pipe_class_default); 9545%} 9546 9547// Shift a postivie int to the left. 9548// Clrlsldi clears the upper 32 bits and shifts. 9549instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9550 match(Set dst (LShiftL (ConvI2L src1) src2)); 9551 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9552 9553 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9554 size(4); 9555 ins_encode %{ 9556 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9557 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9558 %} 9559 ins_pipe(pipe_class_default); 9560%} 9561 9562instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9563 // no match-rule, false predicate 9564 effect(DEF dst, USE src1, USE src2); 9565 predicate(false); 9566 9567 format %{ "SRAW $dst, $src1, $src2" %} 9568 size(4); 9569 ins_encode %{ 9570 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9571 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9572 %} 9573 ins_pipe(pipe_class_default); 9574%} 9575 9576// Register Arithmetic Shift Right 9577instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9578 match(Set dst (RShiftI src1 src2)); 9579 ins_cost(DEFAULT_COST*2); 9580 expand %{ 9581 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9582 iRegIdst tmpI; 9583 maskI_reg_imm(tmpI, src2, mask); 9584 arShiftI_reg_reg(dst, src1, tmpI); 9585 %} 9586%} 9587 9588// Register Arithmetic Shift Right Immediate 9589instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9590 match(Set dst (RShiftI src1 src2)); 9591 9592 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9593 size(4); 9594 ins_encode %{ 9595 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9596 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9597 %} 9598 ins_pipe(pipe_class_default); 9599%} 9600 9601instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9602 // no match-rule, false predicate 9603 effect(DEF dst, USE src1, USE src2); 9604 predicate(false); 9605 9606 format %{ "SRAD $dst, $src1, $src2" %} 9607 size(4); 9608 ins_encode %{ 9609 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9610 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9611 %} 9612 ins_pipe(pipe_class_default); 9613%} 9614 9615// Register Shift Right Arithmetic Long 9616instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9617 match(Set dst (RShiftL src1 src2)); 9618 ins_cost(DEFAULT_COST*2); 9619 9620 expand %{ 9621 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9622 iRegIdst tmpI; 9623 maskI_reg_imm(tmpI, src2, mask); 9624 arShiftL_regL_regI(dst, src1, tmpI); 9625 %} 9626%} 9627 9628// Register Shift Right Immediate 9629instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9630 match(Set dst (RShiftL src1 src2)); 9631 9632 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9633 size(4); 9634 ins_encode %{ 9635 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9636 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9637 %} 9638 ins_pipe(pipe_class_default); 9639%} 9640 9641// RShiftL + ConvL2I 9642instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9643 match(Set dst (ConvL2I (RShiftL src1 src2))); 9644 9645 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9646 size(4); 9647 ins_encode %{ 9648 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9649 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9650 %} 9651 ins_pipe(pipe_class_default); 9652%} 9653 9654instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9655 // no match-rule, false predicate 9656 effect(DEF dst, USE src1, USE src2); 9657 predicate(false); 9658 9659 format %{ "SRW $dst, $src1, $src2" %} 9660 size(4); 9661 ins_encode %{ 9662 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9663 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9664 %} 9665 ins_pipe(pipe_class_default); 9666%} 9667 9668// Register Shift Right 9669instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9670 match(Set dst (URShiftI src1 src2)); 9671 ins_cost(DEFAULT_COST*2); 9672 9673 expand %{ 9674 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9675 iRegIdst tmpI; 9676 maskI_reg_imm(tmpI, src2, mask); 9677 urShiftI_reg_reg(dst, src1, tmpI); 9678 %} 9679%} 9680 9681// Register Shift Right Immediate 9682instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9683 match(Set dst (URShiftI src1 src2)); 9684 9685 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9686 size(4); 9687 ins_encode %{ 9688 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9689 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9690 %} 9691 ins_pipe(pipe_class_default); 9692%} 9693 9694instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9695 // no match-rule, false predicate 9696 effect(DEF dst, USE src1, USE src2); 9697 predicate(false); 9698 9699 format %{ "SRD $dst, $src1, $src2" %} 9700 size(4); 9701 ins_encode %{ 9702 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9703 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9704 %} 9705 ins_pipe(pipe_class_default); 9706%} 9707 9708// Register Shift Right 9709instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9710 match(Set dst (URShiftL src1 src2)); 9711 ins_cost(DEFAULT_COST*2); 9712 9713 expand %{ 9714 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9715 iRegIdst tmpI; 9716 maskI_reg_imm(tmpI, src2, mask); 9717 urShiftL_regL_regI(dst, src1, tmpI); 9718 %} 9719%} 9720 9721// Register Shift Right Immediate 9722instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9723 match(Set dst (URShiftL src1 src2)); 9724 9725 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9726 size(4); 9727 ins_encode %{ 9728 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9729 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9730 %} 9731 ins_pipe(pipe_class_default); 9732%} 9733 9734// URShiftL + ConvL2I. 9735instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9736 match(Set dst (ConvL2I (URShiftL src1 src2))); 9737 9738 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9739 size(4); 9740 ins_encode %{ 9741 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9742 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9743 %} 9744 ins_pipe(pipe_class_default); 9745%} 9746 9747// Register Shift Right Immediate with a CastP2X 9748instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9749 match(Set dst (URShiftL (CastP2X src1) src2)); 9750 9751 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9752 size(4); 9753 ins_encode %{ 9754 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9755 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9756 %} 9757 ins_pipe(pipe_class_default); 9758%} 9759 9760// Bitfield Extract: URShiftI + AndI 9761instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9762 match(Set dst (AndI (URShiftI src1 src2) src3)); 9763 9764 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9765 size(4); 9766 ins_encode %{ 9767 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9768 int rshift = ($src2$$constant) & 0x1f; 9769 int length = log2_long(((jlong) $src3$$constant) + 1); 9770 if (rshift + length > 32) { 9771 // if necessary, adjust mask to omit rotated bits. 9772 length = 32 - rshift; 9773 } 9774 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9775 %} 9776 ins_pipe(pipe_class_default); 9777%} 9778 9779// Bitfield Extract: URShiftL + AndL 9780instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9781 match(Set dst (AndL (URShiftL src1 src2) src3)); 9782 9783 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9784 size(4); 9785 ins_encode %{ 9786 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9787 int rshift = ($src2$$constant) & 0x3f; 9788 int length = log2_long(((jlong) $src3$$constant) + 1); 9789 if (rshift + length > 64) { 9790 // if necessary, adjust mask to omit rotated bits. 9791 length = 64 - rshift; 9792 } 9793 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9794 %} 9795 ins_pipe(pipe_class_default); 9796%} 9797 9798instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9799 match(Set dst (ConvL2I (ConvI2L src))); 9800 9801 format %{ "EXTSW $dst, $src \t// int->int" %} 9802 size(4); 9803 ins_encode %{ 9804 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9805 __ extsw($dst$$Register, $src$$Register); 9806 %} 9807 ins_pipe(pipe_class_default); 9808%} 9809 9810//----------Rotate Instructions------------------------------------------------ 9811 9812// Rotate Left by 8-bit immediate 9813instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9814 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9815 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9816 9817 format %{ "ROTLWI $dst, $src, $lshift" %} 9818 size(4); 9819 ins_encode %{ 9820 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9821 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9822 %} 9823 ins_pipe(pipe_class_default); 9824%} 9825 9826// Rotate Right by 8-bit immediate 9827instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9828 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9829 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9830 9831 format %{ "ROTRWI $dst, $rshift" %} 9832 size(4); 9833 ins_encode %{ 9834 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9835 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9836 %} 9837 ins_pipe(pipe_class_default); 9838%} 9839 9840//----------Floating Point Arithmetic Instructions----------------------------- 9841 9842// Add float single precision 9843instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9844 match(Set dst (AddF src1 src2)); 9845 9846 format %{ "FADDS $dst, $src1, $src2" %} 9847 size(4); 9848 ins_encode %{ 9849 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9850 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9851 %} 9852 ins_pipe(pipe_class_default); 9853%} 9854 9855// Add float double precision 9856instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9857 match(Set dst (AddD src1 src2)); 9858 9859 format %{ "FADD $dst, $src1, $src2" %} 9860 size(4); 9861 ins_encode %{ 9862 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9863 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9864 %} 9865 ins_pipe(pipe_class_default); 9866%} 9867 9868// Sub float single precision 9869instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9870 match(Set dst (SubF src1 src2)); 9871 9872 format %{ "FSUBS $dst, $src1, $src2" %} 9873 size(4); 9874 ins_encode %{ 9875 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9876 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9877 %} 9878 ins_pipe(pipe_class_default); 9879%} 9880 9881// Sub float double precision 9882instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9883 match(Set dst (SubD src1 src2)); 9884 format %{ "FSUB $dst, $src1, $src2" %} 9885 size(4); 9886 ins_encode %{ 9887 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9888 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9889 %} 9890 ins_pipe(pipe_class_default); 9891%} 9892 9893// Mul float single precision 9894instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9895 match(Set dst (MulF src1 src2)); 9896 format %{ "FMULS $dst, $src1, $src2" %} 9897 size(4); 9898 ins_encode %{ 9899 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9900 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9901 %} 9902 ins_pipe(pipe_class_default); 9903%} 9904 9905// Mul float double precision 9906instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9907 match(Set dst (MulD src1 src2)); 9908 format %{ "FMUL $dst, $src1, $src2" %} 9909 size(4); 9910 ins_encode %{ 9911 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9912 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9913 %} 9914 ins_pipe(pipe_class_default); 9915%} 9916 9917// Div float single precision 9918instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9919 match(Set dst (DivF src1 src2)); 9920 format %{ "FDIVS $dst, $src1, $src2" %} 9921 size(4); 9922 ins_encode %{ 9923 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9924 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9925 %} 9926 ins_pipe(pipe_class_default); 9927%} 9928 9929// Div float double precision 9930instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9931 match(Set dst (DivD src1 src2)); 9932 format %{ "FDIV $dst, $src1, $src2" %} 9933 size(4); 9934 ins_encode %{ 9935 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9936 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9937 %} 9938 ins_pipe(pipe_class_default); 9939%} 9940 9941// Absolute float single precision 9942instruct absF_reg(regF dst, regF src) %{ 9943 match(Set dst (AbsF src)); 9944 format %{ "FABS $dst, $src \t// float" %} 9945 size(4); 9946 ins_encode %{ 9947 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9948 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9949 %} 9950 ins_pipe(pipe_class_default); 9951%} 9952 9953// Absolute float double precision 9954instruct absD_reg(regD dst, regD src) %{ 9955 match(Set dst (AbsD src)); 9956 format %{ "FABS $dst, $src \t// double" %} 9957 size(4); 9958 ins_encode %{ 9959 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9960 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9961 %} 9962 ins_pipe(pipe_class_default); 9963%} 9964 9965instruct negF_reg(regF dst, regF src) %{ 9966 match(Set dst (NegF src)); 9967 format %{ "FNEG $dst, $src \t// float" %} 9968 size(4); 9969 ins_encode %{ 9970 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9971 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9972 %} 9973 ins_pipe(pipe_class_default); 9974%} 9975 9976instruct negD_reg(regD dst, regD src) %{ 9977 match(Set dst (NegD src)); 9978 format %{ "FNEG $dst, $src \t// double" %} 9979 size(4); 9980 ins_encode %{ 9981 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9982 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9983 %} 9984 ins_pipe(pipe_class_default); 9985%} 9986 9987// AbsF + NegF. 9988instruct negF_absF_reg(regF dst, regF src) %{ 9989 match(Set dst (NegF (AbsF src))); 9990 format %{ "FNABS $dst, $src \t// float" %} 9991 size(4); 9992 ins_encode %{ 9993 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9994 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9995 %} 9996 ins_pipe(pipe_class_default); 9997%} 9998 9999// AbsD + NegD. 10000instruct negD_absD_reg(regD dst, regD src) %{ 10001 match(Set dst (NegD (AbsD src))); 10002 format %{ "FNABS $dst, $src \t// double" %} 10003 size(4); 10004 ins_encode %{ 10005 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 10006 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 10007 %} 10008 ins_pipe(pipe_class_default); 10009%} 10010 10011// VM_Version::has_fsqrt() decides if this node will be used. 10012// Sqrt float double precision 10013instruct sqrtD_reg(regD dst, regD src) %{ 10014 match(Set dst (SqrtD src)); 10015 format %{ "FSQRT $dst, $src" %} 10016 size(4); 10017 ins_encode %{ 10018 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 10019 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 10020 %} 10021 ins_pipe(pipe_class_default); 10022%} 10023 10024// Single-precision sqrt. 10025instruct sqrtF_reg(regF dst, regF src) %{ 10026 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10027 predicate(VM_Version::has_fsqrts()); 10028 ins_cost(DEFAULT_COST); 10029 10030 format %{ "FSQRTS $dst, $src" %} 10031 size(4); 10032 ins_encode %{ 10033 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 10034 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 10035 %} 10036 ins_pipe(pipe_class_default); 10037%} 10038 10039instruct roundDouble_nop(regD dst) %{ 10040 match(Set dst (RoundDouble dst)); 10041 ins_cost(0); 10042 10043 format %{ " -- \t// RoundDouble not needed - empty" %} 10044 size(0); 10045 // PPC results are already "rounded" (i.e., normal-format IEEE). 10046 ins_encode( /*empty*/ ); 10047 ins_pipe(pipe_class_default); 10048%} 10049 10050instruct roundFloat_nop(regF dst) %{ 10051 match(Set dst (RoundFloat dst)); 10052 ins_cost(0); 10053 10054 format %{ " -- \t// RoundFloat not needed - empty" %} 10055 size(0); 10056 // PPC results are already "rounded" (i.e., normal-format IEEE). 10057 ins_encode( /*empty*/ ); 10058 ins_pipe(pipe_class_default); 10059%} 10060 10061 10062// Multiply-Accumulate 10063// src1 * src2 + src3 10064instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10065 match(Set dst (FmaF src3 (Binary src1 src2))); 10066 10067 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 10068 size(4); 10069 ins_encode %{ 10070 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 10071 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10072 %} 10073 ins_pipe(pipe_class_default); 10074%} 10075 10076// src1 * src2 + src3 10077instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10078 match(Set dst (FmaD src3 (Binary src1 src2))); 10079 10080 format %{ "FMADD $dst, $src1, $src2, $src3" %} 10081 size(4); 10082 ins_encode %{ 10083 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 10084 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10085 %} 10086 ins_pipe(pipe_class_default); 10087%} 10088 10089// -src1 * src2 + src3 = -(src1*src2-src3) 10090instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10091 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 10092 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 10093 10094 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 10095 size(4); 10096 ins_encode %{ 10097 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 10098 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10099 %} 10100 ins_pipe(pipe_class_default); 10101%} 10102 10103// -src1 * src2 + src3 = -(src1*src2-src3) 10104instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10105 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 10106 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 10107 10108 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 10109 size(4); 10110 ins_encode %{ 10111 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 10112 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10113 %} 10114 ins_pipe(pipe_class_default); 10115%} 10116 10117// -src1 * src2 - src3 = -(src1*src2+src3) 10118instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10119 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 10120 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 10121 10122 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 10123 size(4); 10124 ins_encode %{ 10125 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 10126 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10127 %} 10128 ins_pipe(pipe_class_default); 10129%} 10130 10131// -src1 * src2 - src3 = -(src1*src2+src3) 10132instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10133 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 10134 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 10135 10136 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 10137 size(4); 10138 ins_encode %{ 10139 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 10140 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10141 %} 10142 ins_pipe(pipe_class_default); 10143%} 10144 10145// src1 * src2 - src3 10146instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 10147 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 10148 10149 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 10150 size(4); 10151 ins_encode %{ 10152 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 10153 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10154 %} 10155 ins_pipe(pipe_class_default); 10156%} 10157 10158// src1 * src2 - src3 10159instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 10160 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 10161 10162 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 10163 size(4); 10164 ins_encode %{ 10165 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 10166 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 10167 %} 10168 ins_pipe(pipe_class_default); 10169%} 10170 10171 10172//----------Logical Instructions----------------------------------------------- 10173 10174// And Instructions 10175 10176// Register And 10177instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10178 match(Set dst (AndI src1 src2)); 10179 format %{ "AND $dst, $src1, $src2" %} 10180 size(4); 10181 ins_encode %{ 10182 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10183 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10184 %} 10185 ins_pipe(pipe_class_default); 10186%} 10187 10188// Left shifted Immediate And 10189instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 10190 match(Set dst (AndI src1 src2)); 10191 effect(KILL cr0); 10192 format %{ "ANDIS $dst, $src1, $src2.hi" %} 10193 size(4); 10194 ins_encode %{ 10195 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 10196 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 10197 %} 10198 ins_pipe(pipe_class_default); 10199%} 10200 10201// Immediate And 10202instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 10203 match(Set dst (AndI src1 src2)); 10204 effect(KILL cr0); 10205 10206 format %{ "ANDI $dst, $src1, $src2" %} 10207 size(4); 10208 ins_encode %{ 10209 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10210 // FIXME: avoid andi_ ? 10211 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10212 %} 10213 ins_pipe(pipe_class_default); 10214%} 10215 10216// Immediate And where the immediate is a negative power of 2. 10217instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 10218 match(Set dst (AndI src1 src2)); 10219 format %{ "ANDWI $dst, $src1, $src2" %} 10220 size(4); 10221 ins_encode %{ 10222 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10223 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 10224 %} 10225 ins_pipe(pipe_class_default); 10226%} 10227 10228instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 10229 match(Set dst (AndI src1 src2)); 10230 format %{ "ANDWI $dst, $src1, $src2" %} 10231 size(4); 10232 ins_encode %{ 10233 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10234 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10235 %} 10236 ins_pipe(pipe_class_default); 10237%} 10238 10239instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 10240 match(Set dst (AndI src1 src2)); 10241 predicate(UseRotateAndMaskInstructionsPPC64); 10242 format %{ "ANDWI $dst, $src1, $src2" %} 10243 size(4); 10244 ins_encode %{ 10245 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10246 __ rlwinm($dst$$Register, $src1$$Register, 0, 10247 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 10248 %} 10249 ins_pipe(pipe_class_default); 10250%} 10251 10252// Register And Long 10253instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10254 match(Set dst (AndL src1 src2)); 10255 ins_cost(DEFAULT_COST); 10256 10257 format %{ "AND $dst, $src1, $src2 \t// long" %} 10258 size(4); 10259 ins_encode %{ 10260 // TODO: PPC port $archOpcode(ppc64Opcode_and); 10261 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 10262 %} 10263 ins_pipe(pipe_class_default); 10264%} 10265 10266// Immediate And long 10267instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 10268 match(Set dst (AndL src1 src2)); 10269 effect(KILL cr0); 10270 10271 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 10272 size(4); 10273 ins_encode %{ 10274 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10275 // FIXME: avoid andi_ ? 10276 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 10277 %} 10278 ins_pipe(pipe_class_default); 10279%} 10280 10281// Immediate And Long where the immediate is a negative power of 2. 10282instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 10283 match(Set dst (AndL src1 src2)); 10284 format %{ "ANDDI $dst, $src1, $src2" %} 10285 size(4); 10286 ins_encode %{ 10287 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 10288 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 10289 %} 10290 ins_pipe(pipe_class_default); 10291%} 10292 10293instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10294 match(Set dst (AndL src1 src2)); 10295 format %{ "ANDDI $dst, $src1, $src2" %} 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// AndL + ConvL2I. 10305instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 10306 match(Set dst (ConvL2I (AndL src1 src2))); 10307 ins_cost(DEFAULT_COST); 10308 10309 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 10310 size(4); 10311 ins_encode %{ 10312 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10313 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 10314 %} 10315 ins_pipe(pipe_class_default); 10316%} 10317 10318// Or Instructions 10319 10320// Register Or 10321instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10322 match(Set dst (OrI src1 src2)); 10323 format %{ "OR $dst, $src1, $src2" %} 10324 size(4); 10325 ins_encode %{ 10326 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10327 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10328 %} 10329 ins_pipe(pipe_class_default); 10330%} 10331 10332// Expand does not work with above instruct. (??) 10333instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10334 // no match-rule 10335 effect(DEF dst, USE src1, USE src2); 10336 format %{ "OR $dst, $src1, $src2" %} 10337 size(4); 10338 ins_encode %{ 10339 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10340 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10341 %} 10342 ins_pipe(pipe_class_default); 10343%} 10344 10345instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10346 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 10347 ins_cost(DEFAULT_COST*3); 10348 10349 expand %{ 10350 // FIXME: we should do this in the ideal world. 10351 iRegIdst tmp1; 10352 iRegIdst tmp2; 10353 orI_reg_reg(tmp1, src1, src2); 10354 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 10355 orI_reg_reg(dst, tmp1, tmp2); 10356 %} 10357%} 10358 10359// Immediate Or 10360instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10361 match(Set dst (OrI src1 src2)); 10362 format %{ "ORI $dst, $src1, $src2" %} 10363 size(4); 10364 ins_encode %{ 10365 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10366 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 10367 %} 10368 ins_pipe(pipe_class_default); 10369%} 10370 10371// Register Or Long 10372instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10373 match(Set dst (OrL src1 src2)); 10374 ins_cost(DEFAULT_COST); 10375 10376 size(4); 10377 format %{ "OR $dst, $src1, $src2 \t// long" %} 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// OrL + ConvL2I. 10386instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10387 match(Set dst (ConvL2I (OrL src1 src2))); 10388 ins_cost(DEFAULT_COST); 10389 10390 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 10391 size(4); 10392 ins_encode %{ 10393 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10394 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 10395 %} 10396 ins_pipe(pipe_class_default); 10397%} 10398 10399// Immediate Or long 10400instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 10401 match(Set dst (OrL src1 con)); 10402 ins_cost(DEFAULT_COST); 10403 10404 format %{ "ORI $dst, $src1, $con \t// long" %} 10405 size(4); 10406 ins_encode %{ 10407 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 10408 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 10409 %} 10410 ins_pipe(pipe_class_default); 10411%} 10412 10413// Xor Instructions 10414 10415// Register Xor 10416instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10417 match(Set dst (XorI src1 src2)); 10418 format %{ "XOR $dst, $src1, $src2" %} 10419 size(4); 10420 ins_encode %{ 10421 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10422 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10423 %} 10424 ins_pipe(pipe_class_default); 10425%} 10426 10427// Expand does not work with above instruct. (??) 10428instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10429 // no match-rule 10430 effect(DEF dst, USE src1, USE src2); 10431 format %{ "XOR $dst, $src1, $src2" %} 10432 size(4); 10433 ins_encode %{ 10434 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10435 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10436 %} 10437 ins_pipe(pipe_class_default); 10438%} 10439 10440instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10441 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10442 ins_cost(DEFAULT_COST*3); 10443 10444 expand %{ 10445 // FIXME: we should do this in the ideal world. 10446 iRegIdst tmp1; 10447 iRegIdst tmp2; 10448 xorI_reg_reg(tmp1, src1, src2); 10449 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10450 xorI_reg_reg(dst, tmp1, tmp2); 10451 %} 10452%} 10453 10454// Immediate Xor 10455instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10456 match(Set dst (XorI src1 src2)); 10457 format %{ "XORI $dst, $src1, $src2" %} 10458 size(4); 10459 ins_encode %{ 10460 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10461 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10462 %} 10463 ins_pipe(pipe_class_default); 10464%} 10465 10466// Register Xor Long 10467instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10468 match(Set dst (XorL src1 src2)); 10469 ins_cost(DEFAULT_COST); 10470 10471 format %{ "XOR $dst, $src1, $src2 \t// long" %} 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// XorL + ConvL2I. 10481instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10482 match(Set dst (ConvL2I (XorL src1 src2))); 10483 ins_cost(DEFAULT_COST); 10484 10485 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10486 size(4); 10487 ins_encode %{ 10488 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10489 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10490 %} 10491 ins_pipe(pipe_class_default); 10492%} 10493 10494// Immediate Xor Long 10495instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10496 match(Set dst (XorL src1 src2)); 10497 ins_cost(DEFAULT_COST); 10498 10499 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10500 size(4); 10501 ins_encode %{ 10502 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10503 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10504 %} 10505 ins_pipe(pipe_class_default); 10506%} 10507 10508instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10509 match(Set dst (XorI src1 src2)); 10510 ins_cost(DEFAULT_COST); 10511 10512 format %{ "NOT $dst, $src1 ($src2)" %} 10513 size(4); 10514 ins_encode %{ 10515 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10516 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10517 %} 10518 ins_pipe(pipe_class_default); 10519%} 10520 10521instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10522 match(Set dst (XorL src1 src2)); 10523 ins_cost(DEFAULT_COST); 10524 10525 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10526 size(4); 10527 ins_encode %{ 10528 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10529 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10530 %} 10531 ins_pipe(pipe_class_default); 10532%} 10533 10534// And-complement 10535instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10536 match(Set dst (AndI (XorI src1 src2) src3)); 10537 ins_cost(DEFAULT_COST); 10538 10539 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10540 size(4); 10541 ins_encode( enc_andc(dst, src3, src1) ); 10542 ins_pipe(pipe_class_default); 10543%} 10544 10545// And-complement 10546instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10547 // no match-rule, false predicate 10548 effect(DEF dst, USE src1, USE src2); 10549 predicate(false); 10550 10551 format %{ "ANDC $dst, $src1, $src2" %} 10552 size(4); 10553 ins_encode %{ 10554 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10555 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10556 %} 10557 ins_pipe(pipe_class_default); 10558%} 10559 10560//----------Moves between int/long and float/double---------------------------- 10561// 10562// The following rules move values from int/long registers/stack-locations 10563// to float/double registers/stack-locations and vice versa, without doing any 10564// conversions. These rules are used to implement the bit-conversion methods 10565// of java.lang.Float etc., e.g. 10566// int floatToIntBits(float value) 10567// float intBitsToFloat(int bits) 10568// 10569// Notes on the implementation on ppc64: 10570// For Power7 and earlier, the rules are limited to those which move between a 10571// register and a stack-location, because we always have to go through memory 10572// when moving between a float register and an integer register. 10573// This restriction is removed in Power8 with the introduction of the mtfprd 10574// and mffprd instructions. 10575 10576instruct moveL2D_reg(regD dst, iRegLsrc src) %{ 10577 match(Set dst (MoveL2D src)); 10578 predicate(VM_Version::has_mtfprd()); 10579 10580 format %{ "MTFPRD $dst, $src" %} 10581 size(4); 10582 ins_encode %{ 10583 __ mtfprd($dst$$FloatRegister, $src$$Register); 10584 %} 10585 ins_pipe(pipe_class_default); 10586%} 10587 10588instruct moveI2D_reg(regD dst, iRegIsrc src) %{ 10589 // no match-rule, false predicate 10590 effect(DEF dst, USE src); 10591 predicate(false); 10592 10593 format %{ "MTFPRWA $dst, $src" %} 10594 size(4); 10595 ins_encode %{ 10596 __ mtfprwa($dst$$FloatRegister, $src$$Register); 10597 %} 10598 ins_pipe(pipe_class_default); 10599%} 10600 10601//---------- Chain stack slots between similar types -------- 10602 10603// These are needed so that the rules below can match. 10604 10605// Load integer from stack slot 10606instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10607 match(Set dst src); 10608 ins_cost(MEMORY_REF_COST); 10609 10610 format %{ "LWZ $dst, $src" %} 10611 size(4); 10612 ins_encode( enc_lwz(dst, src) ); 10613 ins_pipe(pipe_class_memory); 10614%} 10615 10616// Store integer to stack slot 10617instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10618 match(Set dst src); 10619 ins_cost(MEMORY_REF_COST); 10620 10621 format %{ "STW $src, $dst \t// stk" %} 10622 size(4); 10623 ins_encode( enc_stw(src, dst) ); // rs=rt 10624 ins_pipe(pipe_class_memory); 10625%} 10626 10627// Load long from stack slot 10628instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10629 match(Set dst src); 10630 ins_cost(MEMORY_REF_COST); 10631 10632 format %{ "LD $dst, $src \t// long" %} 10633 size(4); 10634 ins_encode( enc_ld(dst, src) ); 10635 ins_pipe(pipe_class_memory); 10636%} 10637 10638// Store long to stack slot 10639instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10640 match(Set dst src); 10641 ins_cost(MEMORY_REF_COST); 10642 10643 format %{ "STD $src, $dst \t// long" %} 10644 size(4); 10645 ins_encode( enc_std(src, dst) ); // rs=rt 10646 ins_pipe(pipe_class_memory); 10647%} 10648 10649//----------Moves between int and float 10650 10651// Move float value from float stack-location to integer register. 10652instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10653 match(Set dst (MoveF2I src)); 10654 ins_cost(MEMORY_REF_COST); 10655 10656 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10657 size(4); 10658 ins_encode( enc_lwz(dst, src) ); 10659 ins_pipe(pipe_class_memory); 10660%} 10661 10662// Move float value from float register to integer stack-location. 10663instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10664 match(Set dst (MoveF2I src)); 10665 ins_cost(MEMORY_REF_COST); 10666 10667 format %{ "STFS $src, $dst \t// MoveF2I" %} 10668 size(4); 10669 ins_encode( enc_stfs(src, dst) ); 10670 ins_pipe(pipe_class_memory); 10671%} 10672 10673// Move integer value from integer stack-location to float register. 10674instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10675 match(Set dst (MoveI2F src)); 10676 ins_cost(MEMORY_REF_COST); 10677 10678 format %{ "LFS $dst, $src \t// MoveI2F" %} 10679 size(4); 10680 ins_encode %{ 10681 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10682 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10683 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10684 %} 10685 ins_pipe(pipe_class_memory); 10686%} 10687 10688// Move integer value from integer register to float stack-location. 10689instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10690 match(Set dst (MoveI2F src)); 10691 ins_cost(MEMORY_REF_COST); 10692 10693 format %{ "STW $src, $dst \t// MoveI2F" %} 10694 size(4); 10695 ins_encode( enc_stw(src, dst) ); 10696 ins_pipe(pipe_class_memory); 10697%} 10698 10699//----------Moves between long and float 10700 10701instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10702 // no match-rule, false predicate 10703 effect(DEF dst, USE src); 10704 predicate(false); 10705 10706 format %{ "storeD $src, $dst \t// STACK" %} 10707 size(4); 10708 ins_encode( enc_stfd(src, dst) ); 10709 ins_pipe(pipe_class_default); 10710%} 10711 10712//----------Moves between long and double 10713 10714// Move double value from double stack-location to long register. 10715instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10716 match(Set dst (MoveD2L src)); 10717 ins_cost(MEMORY_REF_COST); 10718 size(4); 10719 format %{ "LD $dst, $src \t// MoveD2L" %} 10720 ins_encode( enc_ld(dst, src) ); 10721 ins_pipe(pipe_class_memory); 10722%} 10723 10724// Move double value from double register to long stack-location. 10725instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10726 match(Set dst (MoveD2L src)); 10727 effect(DEF dst, USE src); 10728 ins_cost(MEMORY_REF_COST); 10729 10730 format %{ "STFD $src, $dst \t// MoveD2L" %} 10731 size(4); 10732 ins_encode( enc_stfd(src, dst) ); 10733 ins_pipe(pipe_class_memory); 10734%} 10735 10736// Move long value from long stack-location to double register. 10737instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10738 match(Set dst (MoveL2D src)); 10739 ins_cost(MEMORY_REF_COST); 10740 10741 format %{ "LFD $dst, $src \t// MoveL2D" %} 10742 size(4); 10743 ins_encode( enc_lfd(dst, src) ); 10744 ins_pipe(pipe_class_memory); 10745%} 10746 10747// Move long value from long register to double stack-location. 10748instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10749 match(Set dst (MoveL2D src)); 10750 ins_cost(MEMORY_REF_COST); 10751 10752 format %{ "STD $src, $dst \t// MoveL2D" %} 10753 size(4); 10754 ins_encode( enc_std(src, dst) ); 10755 ins_pipe(pipe_class_memory); 10756%} 10757 10758//----------Register Move Instructions----------------------------------------- 10759 10760// Replicate for Superword 10761 10762instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10763 predicate(false); 10764 effect(DEF dst, USE src); 10765 10766 format %{ "MR $dst, $src \t// replicate " %} 10767 // variable size, 0 or 4. 10768 ins_encode %{ 10769 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10770 __ mr_if_needed($dst$$Register, $src$$Register); 10771 %} 10772 ins_pipe(pipe_class_default); 10773%} 10774 10775//----------Cast instructions (Java-level type cast)--------------------------- 10776 10777// Cast Long to Pointer for unsafe natives. 10778instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10779 match(Set dst (CastX2P src)); 10780 10781 format %{ "MR $dst, $src \t// Long->Ptr" %} 10782 // variable size, 0 or 4. 10783 ins_encode %{ 10784 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10785 __ mr_if_needed($dst$$Register, $src$$Register); 10786 %} 10787 ins_pipe(pipe_class_default); 10788%} 10789 10790// Cast Pointer to Long for unsafe natives. 10791instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10792 match(Set dst (CastP2X src)); 10793 10794 format %{ "MR $dst, $src \t// Ptr->Long" %} 10795 // variable size, 0 or 4. 10796 ins_encode %{ 10797 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10798 __ mr_if_needed($dst$$Register, $src$$Register); 10799 %} 10800 ins_pipe(pipe_class_default); 10801%} 10802 10803instruct castPP(iRegPdst dst) %{ 10804 match(Set dst (CastPP dst)); 10805 format %{ " -- \t// castPP of $dst" %} 10806 size(0); 10807 ins_encode( /*empty*/ ); 10808 ins_pipe(pipe_class_default); 10809%} 10810 10811instruct castII(iRegIdst dst) %{ 10812 match(Set dst (CastII dst)); 10813 format %{ " -- \t// castII of $dst" %} 10814 size(0); 10815 ins_encode( /*empty*/ ); 10816 ins_pipe(pipe_class_default); 10817%} 10818 10819instruct checkCastPP(iRegPdst dst) %{ 10820 match(Set dst (CheckCastPP dst)); 10821 format %{ " -- \t// checkcastPP of $dst" %} 10822 size(0); 10823 ins_encode( /*empty*/ ); 10824 ins_pipe(pipe_class_default); 10825%} 10826 10827//----------Convert instructions----------------------------------------------- 10828 10829// Convert to boolean. 10830 10831// int_to_bool(src) : { 1 if src != 0 10832// { 0 else 10833// 10834// strategy: 10835// 1) Count leading zeros of 32 bit-value src, 10836// this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10837// 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10838// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10839 10840// convI2Bool 10841instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10842 match(Set dst (Conv2B src)); 10843 predicate(UseCountLeadingZerosInstructionsPPC64); 10844 ins_cost(DEFAULT_COST); 10845 10846 expand %{ 10847 immI shiftAmount %{ 0x5 %} 10848 uimmI16 mask %{ 0x1 %} 10849 iRegIdst tmp1; 10850 iRegIdst tmp2; 10851 countLeadingZerosI(tmp1, src); 10852 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10853 xorI_reg_uimm16(dst, tmp2, mask); 10854 %} 10855%} 10856 10857instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10858 match(Set dst (Conv2B src)); 10859 effect(TEMP crx); 10860 predicate(!UseCountLeadingZerosInstructionsPPC64); 10861 ins_cost(DEFAULT_COST); 10862 10863 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10864 "LI $dst, #0\n\t" 10865 "BEQ $crx, done\n\t" 10866 "LI $dst, #1\n" 10867 "done:" %} 10868 size(16); 10869 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10870 ins_pipe(pipe_class_compare); 10871%} 10872 10873// ConvI2B + XorI 10874instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10875 match(Set dst (XorI (Conv2B src) mask)); 10876 predicate(UseCountLeadingZerosInstructionsPPC64); 10877 ins_cost(DEFAULT_COST); 10878 10879 expand %{ 10880 immI shiftAmount %{ 0x5 %} 10881 iRegIdst tmp1; 10882 countLeadingZerosI(tmp1, src); 10883 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10884 %} 10885%} 10886 10887instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10888 match(Set dst (XorI (Conv2B src) mask)); 10889 effect(TEMP crx); 10890 predicate(!UseCountLeadingZerosInstructionsPPC64); 10891 ins_cost(DEFAULT_COST); 10892 10893 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10894 "LI $dst, #1\n\t" 10895 "BEQ $crx, done\n\t" 10896 "LI $dst, #0\n" 10897 "done:" %} 10898 size(16); 10899 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10900 ins_pipe(pipe_class_compare); 10901%} 10902 10903// AndI 0b0..010..0 + ConvI2B 10904instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10905 match(Set dst (Conv2B (AndI src mask))); 10906 predicate(UseRotateAndMaskInstructionsPPC64); 10907 ins_cost(DEFAULT_COST); 10908 10909 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10910 size(4); 10911 ins_encode %{ 10912 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10913 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10914 %} 10915 ins_pipe(pipe_class_default); 10916%} 10917 10918// Convert pointer to boolean. 10919// 10920// ptr_to_bool(src) : { 1 if src != 0 10921// { 0 else 10922// 10923// strategy: 10924// 1) Count leading zeros of 64 bit-value src, 10925// this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10926// 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10927// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10928 10929// ConvP2B 10930instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10931 match(Set dst (Conv2B src)); 10932 predicate(UseCountLeadingZerosInstructionsPPC64); 10933 ins_cost(DEFAULT_COST); 10934 10935 expand %{ 10936 immI shiftAmount %{ 0x6 %} 10937 uimmI16 mask %{ 0x1 %} 10938 iRegIdst tmp1; 10939 iRegIdst tmp2; 10940 countLeadingZerosP(tmp1, src); 10941 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10942 xorI_reg_uimm16(dst, tmp2, mask); 10943 %} 10944%} 10945 10946instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10947 match(Set dst (Conv2B src)); 10948 effect(TEMP crx); 10949 predicate(!UseCountLeadingZerosInstructionsPPC64); 10950 ins_cost(DEFAULT_COST); 10951 10952 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10953 "LI $dst, #0\n\t" 10954 "BEQ $crx, done\n\t" 10955 "LI $dst, #1\n" 10956 "done:" %} 10957 size(16); 10958 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10959 ins_pipe(pipe_class_compare); 10960%} 10961 10962// ConvP2B + XorI 10963instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10964 match(Set dst (XorI (Conv2B src) mask)); 10965 predicate(UseCountLeadingZerosInstructionsPPC64); 10966 ins_cost(DEFAULT_COST); 10967 10968 expand %{ 10969 immI shiftAmount %{ 0x6 %} 10970 iRegIdst tmp1; 10971 countLeadingZerosP(tmp1, src); 10972 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10973 %} 10974%} 10975 10976instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10977 match(Set dst (XorI (Conv2B src) mask)); 10978 effect(TEMP crx); 10979 predicate(!UseCountLeadingZerosInstructionsPPC64); 10980 ins_cost(DEFAULT_COST); 10981 10982 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10983 "LI $dst, #1\n\t" 10984 "BEQ $crx, done\n\t" 10985 "LI $dst, #0\n" 10986 "done:" %} 10987 size(16); 10988 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10989 ins_pipe(pipe_class_compare); 10990%} 10991 10992// if src1 < src2, return -1 else return 0 10993instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10994 match(Set dst (CmpLTMask src1 src2)); 10995 ins_cost(DEFAULT_COST*4); 10996 10997 expand %{ 10998 iRegLdst src1s; 10999 iRegLdst src2s; 11000 iRegLdst diff; 11001 convI2L_reg(src1s, src1); // Ensure proper sign extension. 11002 convI2L_reg(src2s, src2); // Ensure proper sign extension. 11003 subL_reg_reg(diff, src1s, src2s); 11004 // Need to consider >=33 bit result, therefore we need signmaskL. 11005 signmask64I_regL(dst, diff); 11006 %} 11007%} 11008 11009instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 11010 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 11011 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 11012 size(4); 11013 ins_encode %{ 11014 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 11015 __ srawi($dst$$Register, $src1$$Register, 0x1f); 11016 %} 11017 ins_pipe(pipe_class_default); 11018%} 11019 11020//----------Arithmetic Conversion Instructions--------------------------------- 11021 11022// Convert to Byte -- nop 11023// Convert to Short -- nop 11024 11025// Convert to Int 11026 11027instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 11028 match(Set dst (RShiftI (LShiftI src amount) amount)); 11029 format %{ "EXTSB $dst, $src \t// byte->int" %} 11030 size(4); 11031 ins_encode %{ 11032 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 11033 __ extsb($dst$$Register, $src$$Register); 11034 %} 11035 ins_pipe(pipe_class_default); 11036%} 11037 11038instruct extsh(iRegIdst dst, iRegIsrc src) %{ 11039 effect(DEF dst, USE src); 11040 11041 size(4); 11042 ins_encode %{ 11043 __ extsh($dst$$Register, $src$$Register); 11044 %} 11045 ins_pipe(pipe_class_default); 11046%} 11047 11048// LShiftI 16 + RShiftI 16 converts short to int. 11049instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 11050 match(Set dst (RShiftI (LShiftI src amount) amount)); 11051 format %{ "EXTSH $dst, $src \t// short->int" %} 11052 size(4); 11053 ins_encode %{ 11054 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 11055 __ extsh($dst$$Register, $src$$Register); 11056 %} 11057 ins_pipe(pipe_class_default); 11058%} 11059 11060// ConvL2I + ConvI2L: Sign extend int in long register. 11061instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 11062 match(Set dst (ConvI2L (ConvL2I src))); 11063 11064 format %{ "EXTSW $dst, $src \t// long->long" %} 11065 size(4); 11066 ins_encode %{ 11067 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11068 __ extsw($dst$$Register, $src$$Register); 11069 %} 11070 ins_pipe(pipe_class_default); 11071%} 11072 11073instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 11074 match(Set dst (ConvL2I src)); 11075 format %{ "MR $dst, $src \t// long->int" %} 11076 // variable size, 0 or 4 11077 ins_encode %{ 11078 // TODO: PPC port $archOpcode(ppc64Opcode_or); 11079 __ mr_if_needed($dst$$Register, $src$$Register); 11080 %} 11081 ins_pipe(pipe_class_default); 11082%} 11083 11084instruct convD2IRaw_regD(regD dst, regD src) %{ 11085 // no match-rule, false predicate 11086 effect(DEF dst, USE src); 11087 predicate(false); 11088 11089 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 11090 size(4); 11091 ins_encode %{ 11092 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 11093 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11094 %} 11095 ins_pipe(pipe_class_default); 11096%} 11097 11098instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL 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_stackSlotL(dst, crx, src) ); 11109 ins_pipe(pipe_class_default); 11110%} 11111 11112instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11113 // no match-rule, false predicate 11114 effect(DEF dst, USE crx, USE src); 11115 predicate(false); 11116 11117 ins_variable_size_depending_on_alignment(true); 11118 11119 format %{ "cmovI $crx, $dst, $src" %} 11120 // Worst case is branch + move + stop, no stop without scheduler. 11121 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 11122 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11123 ins_pipe(pipe_class_default); 11124%} 11125 11126instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11127 // no match-rule, false predicate 11128 effect(DEF dst, USE crx, USE mem); 11129 predicate(false); 11130 11131 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 11132 postalloc_expand %{ 11133 // 11134 // replaces 11135 // 11136 // region dst crx mem 11137 // \ | | / 11138 // dst=cmovI_bso_stackSlotL_conLvalue0 11139 // 11140 // with 11141 // 11142 // region dst 11143 // \ / 11144 // dst=loadConI16(0) 11145 // | 11146 // ^ region dst crx mem 11147 // | \ | | / 11148 // dst=cmovI_bso_stackSlotL 11149 // 11150 11151 // Create new nodes. 11152 MachNode *m1 = new loadConI16Node(); 11153 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 11154 11155 // inputs for new nodes 11156 m1->add_req(n_region); 11157 m2->add_req(n_region, n_crx, n_mem); 11158 11159 // precedences for new nodes 11160 m2->add_prec(m1); 11161 11162 // operands for new nodes 11163 m1->_opnds[0] = op_dst; 11164 m1->_opnds[1] = new immI16Oper(0); 11165 11166 m2->_opnds[0] = op_dst; 11167 m2->_opnds[1] = op_crx; 11168 m2->_opnds[2] = op_mem; 11169 11170 // registers for new nodes 11171 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11172 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11173 11174 // Insert new nodes. 11175 nodes->push(m1); 11176 nodes->push(m2); 11177 %} 11178%} 11179 11180instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{ 11181 // no match-rule, false predicate 11182 effect(DEF dst, USE crx, USE src); 11183 predicate(false); 11184 11185 format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %} 11186 postalloc_expand %{ 11187 // 11188 // replaces 11189 // 11190 // region dst crx src 11191 // \ | | / 11192 // dst=cmovI_bso_reg_conLvalue0 11193 // 11194 // with 11195 // 11196 // region dst 11197 // \ / 11198 // dst=loadConI16(0) 11199 // | 11200 // ^ region dst crx src 11201 // | \ | | / 11202 // dst=cmovI_bso_reg 11203 // 11204 11205 // Create new nodes. 11206 MachNode *m1 = new loadConI16Node(); 11207 MachNode *m2 = new cmovI_bso_regNode(); 11208 11209 // inputs for new nodes 11210 m1->add_req(n_region); 11211 m2->add_req(n_region, n_crx, n_src); 11212 11213 // precedences for new nodes 11214 m2->add_prec(m1); 11215 11216 // operands for new nodes 11217 m1->_opnds[0] = op_dst; 11218 m1->_opnds[1] = new immI16Oper(0); 11219 11220 m2->_opnds[0] = op_dst; 11221 m2->_opnds[1] = op_crx; 11222 m2->_opnds[2] = op_src; 11223 11224 // registers for new nodes 11225 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11226 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11227 11228 // Insert new nodes. 11229 nodes->push(m1); 11230 nodes->push(m2); 11231 %} 11232%} 11233 11234// Double to Int conversion, NaN is mapped to 0. 11235instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 11236 match(Set dst (ConvD2I src)); 11237 predicate(!VM_Version::has_mtfprd()); 11238 ins_cost(DEFAULT_COST); 11239 11240 expand %{ 11241 regD tmpD; 11242 stackSlotL tmpS; 11243 flagsReg crx; 11244 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11245 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11246 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11247 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11248 %} 11249%} 11250 11251// Double to Int conversion, NaN is mapped to 0. Special version for Power8. 11252instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{ 11253 match(Set dst (ConvD2I src)); 11254 predicate(VM_Version::has_mtfprd()); 11255 ins_cost(DEFAULT_COST); 11256 11257 expand %{ 11258 regD tmpD; 11259 flagsReg crx; 11260 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11261 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 11262 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11263 %} 11264%} 11265 11266instruct convF2IRaw_regF(regF dst, regF src) %{ 11267 // no match-rule, false predicate 11268 effect(DEF dst, USE src); 11269 predicate(false); 11270 11271 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 11272 size(4); 11273 ins_encode %{ 11274 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11275 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 11276 %} 11277 ins_pipe(pipe_class_default); 11278%} 11279 11280// Float to Int conversion, NaN is mapped to 0. 11281instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 11282 match(Set dst (ConvF2I src)); 11283 predicate(!VM_Version::has_mtfprd()); 11284 ins_cost(DEFAULT_COST); 11285 11286 expand %{ 11287 regF tmpF; 11288 stackSlotL tmpS; 11289 flagsReg crx; 11290 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11291 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11292 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11293 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11294 %} 11295%} 11296 11297// Float to Int conversion, NaN is mapped to 0. Special version for Power8. 11298instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{ 11299 match(Set dst (ConvF2I src)); 11300 predicate(VM_Version::has_mtfprd()); 11301 ins_cost(DEFAULT_COST); 11302 11303 expand %{ 11304 regF tmpF; 11305 flagsReg crx; 11306 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11307 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 11308 cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11309 %} 11310%} 11311 11312// Convert to Long 11313 11314instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 11315 match(Set dst (ConvI2L src)); 11316 format %{ "EXTSW $dst, $src \t// int->long" %} 11317 size(4); 11318 ins_encode %{ 11319 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 11320 __ extsw($dst$$Register, $src$$Register); 11321 %} 11322 ins_pipe(pipe_class_default); 11323%} 11324 11325// Zero-extend: convert unsigned int to long (convUI2L). 11326instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 11327 match(Set dst (AndL (ConvI2L 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// Zero-extend: convert unsigned int to long in long register. 11340instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 11341 match(Set dst (AndL src mask)); 11342 ins_cost(DEFAULT_COST); 11343 11344 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 11345 size(4); 11346 ins_encode %{ 11347 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 11348 __ clrldi($dst$$Register, $src$$Register, 32); 11349 %} 11350 ins_pipe(pipe_class_default); 11351%} 11352 11353instruct convF2LRaw_regF(regF dst, regF src) %{ 11354 // no match-rule, false predicate 11355 effect(DEF dst, USE src); 11356 predicate(false); 11357 11358 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 11359 size(4); 11360 ins_encode %{ 11361 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11362 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11363 %} 11364 ins_pipe(pipe_class_default); 11365%} 11366 11367instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL 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_stackSlotL(dst, crx, src) ); 11378 ins_pipe(pipe_class_default); 11379%} 11380 11381instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11382 // no match-rule, false predicate 11383 effect(DEF dst, USE crx, USE src); 11384 predicate(false); 11385 11386 ins_variable_size_depending_on_alignment(true); 11387 11388 format %{ "cmovL $crx, $dst, $src" %} 11389 // Worst case is branch + move + stop, no stop without scheduler. 11390 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 11391 ins_encode( enc_cmove_bso_reg(dst, crx, src) ); 11392 ins_pipe(pipe_class_default); 11393%} 11394 11395instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 11396 // no match-rule, false predicate 11397 effect(DEF dst, USE crx, USE mem); 11398 predicate(false); 11399 11400 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 11401 postalloc_expand %{ 11402 // 11403 // replaces 11404 // 11405 // region dst crx mem 11406 // \ | | / 11407 // dst=cmovL_bso_stackSlotL_conLvalue0 11408 // 11409 // with 11410 // 11411 // region dst 11412 // \ / 11413 // dst=loadConL16(0) 11414 // | 11415 // ^ region dst crx mem 11416 // | \ | | / 11417 // dst=cmovL_bso_stackSlotL 11418 // 11419 11420 // Create new nodes. 11421 MachNode *m1 = new loadConL16Node(); 11422 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 11423 11424 // inputs for new nodes 11425 m1->add_req(n_region); 11426 m2->add_req(n_region, n_crx, n_mem); 11427 m2->add_prec(m1); 11428 11429 // operands for new nodes 11430 m1->_opnds[0] = op_dst; 11431 m1->_opnds[1] = new immL16Oper(0); 11432 m2->_opnds[0] = op_dst; 11433 m2->_opnds[1] = op_crx; 11434 m2->_opnds[2] = op_mem; 11435 11436 // registers for new nodes 11437 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11438 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11439 11440 // Insert new nodes. 11441 nodes->push(m1); 11442 nodes->push(m2); 11443 %} 11444%} 11445 11446instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{ 11447 // no match-rule, false predicate 11448 effect(DEF dst, USE crx, USE src); 11449 predicate(false); 11450 11451 format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %} 11452 postalloc_expand %{ 11453 // 11454 // replaces 11455 // 11456 // region dst crx src 11457 // \ | | / 11458 // dst=cmovL_bso_reg_conLvalue0 11459 // 11460 // with 11461 // 11462 // region dst 11463 // \ / 11464 // dst=loadConL16(0) 11465 // | 11466 // ^ region dst crx src 11467 // | \ | | / 11468 // dst=cmovL_bso_reg 11469 // 11470 11471 // Create new nodes. 11472 MachNode *m1 = new loadConL16Node(); 11473 MachNode *m2 = new cmovL_bso_regNode(); 11474 11475 // inputs for new nodes 11476 m1->add_req(n_region); 11477 m2->add_req(n_region, n_crx, n_src); 11478 m2->add_prec(m1); 11479 11480 // operands for new nodes 11481 m1->_opnds[0] = op_dst; 11482 m1->_opnds[1] = new immL16Oper(0); 11483 m2->_opnds[0] = op_dst; 11484 m2->_opnds[1] = op_crx; 11485 m2->_opnds[2] = op_src; 11486 11487 // registers for new nodes 11488 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11489 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11490 11491 // Insert new nodes. 11492 nodes->push(m1); 11493 nodes->push(m2); 11494 %} 11495%} 11496 11497// Float to Long conversion, NaN is mapped to 0. 11498instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 11499 match(Set dst (ConvF2L src)); 11500 predicate(!VM_Version::has_mtfprd()); 11501 ins_cost(DEFAULT_COST); 11502 11503 expand %{ 11504 regF tmpF; 11505 stackSlotL tmpS; 11506 flagsReg crx; 11507 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11508 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11509 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 11510 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11511 %} 11512%} 11513 11514// Float to Long conversion, NaN is mapped to 0. Special version for Power8. 11515instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{ 11516 match(Set dst (ConvF2L src)); 11517 predicate(VM_Version::has_mtfprd()); 11518 ins_cost(DEFAULT_COST); 11519 11520 expand %{ 11521 regF tmpF; 11522 flagsReg crx; 11523 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11524 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 11525 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check. 11526 %} 11527%} 11528 11529instruct convD2LRaw_regD(regD dst, regD src) %{ 11530 // no match-rule, false predicate 11531 effect(DEF dst, USE src); 11532 predicate(false); 11533 11534 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 11535 size(4); 11536 ins_encode %{ 11537 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 11538 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 11539 %} 11540 ins_pipe(pipe_class_default); 11541%} 11542 11543// Double to Long conversion, NaN is mapped to 0. 11544instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 11545 match(Set dst (ConvD2L src)); 11546 predicate(!VM_Version::has_mtfprd()); 11547 ins_cost(DEFAULT_COST); 11548 11549 expand %{ 11550 regD tmpD; 11551 stackSlotL tmpS; 11552 flagsReg crx; 11553 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11554 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11555 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 11556 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 11557 %} 11558%} 11559 11560// Double to Long conversion, NaN is mapped to 0. Special version for Power8. 11561instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{ 11562 match(Set dst (ConvD2L src)); 11563 predicate(VM_Version::has_mtfprd()); 11564 ins_cost(DEFAULT_COST); 11565 11566 expand %{ 11567 regD tmpD; 11568 flagsReg crx; 11569 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 11570 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 11571 cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check. 11572 %} 11573%} 11574 11575// Convert to Float 11576 11577// Placed here as needed in expand. 11578instruct convL2DRaw_regD(regD dst, regD src) %{ 11579 // no match-rule, false predicate 11580 effect(DEF dst, USE src); 11581 predicate(false); 11582 11583 format %{ "FCFID $dst, $src \t// convL2D" %} 11584 size(4); 11585 ins_encode %{ 11586 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11587 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 11588 %} 11589 ins_pipe(pipe_class_default); 11590%} 11591 11592// Placed here as needed in expand. 11593instruct convD2F_reg(regF dst, regD src) %{ 11594 match(Set dst (ConvD2F src)); 11595 format %{ "FRSP $dst, $src \t// convD2F" %} 11596 size(4); 11597 ins_encode %{ 11598 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 11599 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 11600 %} 11601 ins_pipe(pipe_class_default); 11602%} 11603 11604// Integer to Float conversion. 11605instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 11606 match(Set dst (ConvI2F src)); 11607 predicate(!VM_Version::has_fcfids()); 11608 ins_cost(DEFAULT_COST); 11609 11610 expand %{ 11611 iRegLdst tmpL; 11612 stackSlotL tmpS; 11613 regD tmpD; 11614 regD tmpD2; 11615 convI2L_reg(tmpL, src); // Sign-extension int to long. 11616 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11617 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11618 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 11619 convD2F_reg(dst, tmpD2); // Convert double to float. 11620 %} 11621%} 11622 11623instruct convL2FRaw_regF(regF dst, regD src) %{ 11624 // no match-rule, false predicate 11625 effect(DEF dst, USE src); 11626 predicate(false); 11627 11628 format %{ "FCFIDS $dst, $src \t// convL2F" %} 11629 size(4); 11630 ins_encode %{ 11631 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 11632 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 11633 %} 11634 ins_pipe(pipe_class_default); 11635%} 11636 11637// Integer to Float conversion. Special version for Power7. 11638instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 11639 match(Set dst (ConvI2F src)); 11640 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11641 ins_cost(DEFAULT_COST); 11642 11643 expand %{ 11644 iRegLdst tmpL; 11645 stackSlotL tmpS; 11646 regD tmpD; 11647 convI2L_reg(tmpL, src); // Sign-extension int to long. 11648 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11649 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11650 convL2FRaw_regF(dst, tmpD); // Convert to float. 11651 %} 11652%} 11653 11654// Integer to Float conversion. Special version for Power8. 11655instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{ 11656 match(Set dst (ConvI2F src)); 11657 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11658 ins_cost(DEFAULT_COST); 11659 11660 expand %{ 11661 regD tmpD; 11662 moveI2D_reg(tmpD, src); 11663 convL2FRaw_regF(dst, tmpD); // Convert to float. 11664 %} 11665%} 11666 11667// L2F to avoid runtime call. 11668instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 11669 match(Set dst (ConvL2F src)); 11670 predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd()); 11671 ins_cost(DEFAULT_COST); 11672 11673 expand %{ 11674 stackSlotL tmpS; 11675 regD tmpD; 11676 regL_to_stkL(tmpS, src); // Store long to stack. 11677 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11678 convL2FRaw_regF(dst, tmpD); // Convert to float. 11679 %} 11680%} 11681 11682// L2F to avoid runtime call. Special version for Power8. 11683instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{ 11684 match(Set dst (ConvL2F src)); 11685 predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd()); 11686 ins_cost(DEFAULT_COST); 11687 11688 expand %{ 11689 regD tmpD; 11690 moveL2D_reg(tmpD, src); 11691 convL2FRaw_regF(dst, tmpD); // Convert to float. 11692 %} 11693%} 11694 11695// Moved up as used in expand. 11696//instruct convD2F_reg(regF dst, regD src) %{%} 11697 11698// Convert to Double 11699 11700// Integer to Double conversion. 11701instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11702 match(Set dst (ConvI2D src)); 11703 predicate(!VM_Version::has_mtfprd()); 11704 ins_cost(DEFAULT_COST); 11705 11706 expand %{ 11707 iRegLdst tmpL; 11708 stackSlotL tmpS; 11709 regD tmpD; 11710 convI2L_reg(tmpL, src); // Sign-extension int to long. 11711 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11712 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11713 convL2DRaw_regD(dst, tmpD); // Convert to double. 11714 %} 11715%} 11716 11717// Integer to Double conversion. Special version for Power8. 11718instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{ 11719 match(Set dst (ConvI2D src)); 11720 predicate(VM_Version::has_mtfprd()); 11721 ins_cost(DEFAULT_COST); 11722 11723 expand %{ 11724 regD tmpD; 11725 moveI2D_reg(tmpD, src); 11726 convL2DRaw_regD(dst, tmpD); // Convert to double. 11727 %} 11728%} 11729 11730// Long to Double conversion 11731instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11732 match(Set dst (ConvL2D src)); 11733 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11734 11735 expand %{ 11736 regD tmpD; 11737 moveL2D_stack_reg(tmpD, src); 11738 convL2DRaw_regD(dst, tmpD); 11739 %} 11740%} 11741 11742// Long to Double conversion. Special version for Power8. 11743instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{ 11744 match(Set dst (ConvL2D src)); 11745 predicate(VM_Version::has_mtfprd()); 11746 ins_cost(DEFAULT_COST); 11747 11748 expand %{ 11749 regD tmpD; 11750 moveL2D_reg(tmpD, src); 11751 convL2DRaw_regD(dst, tmpD); // Convert to double. 11752 %} 11753%} 11754 11755instruct convF2D_reg(regD dst, regF src) %{ 11756 match(Set dst (ConvF2D src)); 11757 format %{ "FMR $dst, $src \t// float->double" %} 11758 // variable size, 0 or 4 11759 ins_encode %{ 11760 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11761 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11762 %} 11763 ins_pipe(pipe_class_default); 11764%} 11765 11766//----------Control Flow Instructions------------------------------------------ 11767// Compare Instructions 11768 11769// Compare Integers 11770instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11771 match(Set crx (CmpI src1 src2)); 11772 size(4); 11773 format %{ "CMPW $crx, $src1, $src2" %} 11774 ins_encode %{ 11775 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11776 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11777 %} 11778 ins_pipe(pipe_class_compare); 11779%} 11780 11781instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11782 match(Set crx (CmpI src1 src2)); 11783 format %{ "CMPWI $crx, $src1, $src2" %} 11784 size(4); 11785 ins_encode %{ 11786 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11787 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11788 %} 11789 ins_pipe(pipe_class_compare); 11790%} 11791 11792// (src1 & src2) == 0? 11793instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11794 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11795 // r0 is killed 11796 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11797 size(4); 11798 ins_encode %{ 11799 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11800 __ andi_(R0, $src1$$Register, $src2$$constant); 11801 %} 11802 ins_pipe(pipe_class_compare); 11803%} 11804 11805instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11806 match(Set crx (CmpL src1 src2)); 11807 format %{ "CMPD $crx, $src1, $src2" %} 11808 size(4); 11809 ins_encode %{ 11810 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11811 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11812 %} 11813 ins_pipe(pipe_class_compare); 11814%} 11815 11816instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11817 match(Set crx (CmpL src1 src2)); 11818 format %{ "CMPDI $crx, $src1, $src2" %} 11819 size(4); 11820 ins_encode %{ 11821 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11822 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11823 %} 11824 ins_pipe(pipe_class_compare); 11825%} 11826 11827// Added CmpUL for LoopPredicate. 11828instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11829 match(Set crx (CmpUL src1 src2)); 11830 format %{ "CMPLD $crx, $src1, $src2" %} 11831 size(4); 11832 ins_encode %{ 11833 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11834 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11835 %} 11836 ins_pipe(pipe_class_compare); 11837%} 11838 11839instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11840 match(Set crx (CmpUL src1 src2)); 11841 format %{ "CMPLDI $crx, $src1, $src2" %} 11842 size(4); 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11845 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11846 %} 11847 ins_pipe(pipe_class_compare); 11848%} 11849 11850instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11851 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11852 // r0 is killed 11853 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11854 size(4); 11855 ins_encode %{ 11856 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11857 __ and_(R0, $src1$$Register, $src2$$Register); 11858 %} 11859 ins_pipe(pipe_class_compare); 11860%} 11861 11862instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11863 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11864 // r0 is killed 11865 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11866 size(4); 11867 ins_encode %{ 11868 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11869 __ andi_(R0, $src1$$Register, $src2$$constant); 11870 %} 11871 ins_pipe(pipe_class_compare); 11872%} 11873 11874instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11875 // no match-rule, false predicate 11876 effect(DEF dst, USE crx); 11877 predicate(false); 11878 11879 ins_variable_size_depending_on_alignment(true); 11880 11881 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11882 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11883 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11884 ins_encode %{ 11885 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11886 Label done; 11887 // li(Rdst, 0); // equal -> 0 11888 __ beq($crx$$CondRegister, done); 11889 __ li($dst$$Register, 1); // greater -> +1 11890 __ bgt($crx$$CondRegister, done); 11891 __ li($dst$$Register, -1); // unordered or less -> -1 11892 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11893 __ bind(done); 11894 %} 11895 ins_pipe(pipe_class_compare); 11896%} 11897 11898instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11899 // no match-rule, false predicate 11900 effect(DEF dst, USE crx); 11901 predicate(false); 11902 11903 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11904 postalloc_expand %{ 11905 // 11906 // replaces 11907 // 11908 // region crx 11909 // \ | 11910 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11911 // 11912 // with 11913 // 11914 // region 11915 // \ 11916 // dst=loadConI16(0) 11917 // | 11918 // ^ region crx 11919 // | \ | 11920 // dst=cmovI_conIvalueMinus1_conIvalue1 11921 // 11922 11923 // Create new nodes. 11924 MachNode *m1 = new loadConI16Node(); 11925 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11926 11927 // inputs for new nodes 11928 m1->add_req(n_region); 11929 m2->add_req(n_region, n_crx); 11930 m2->add_prec(m1); 11931 11932 // operands for new nodes 11933 m1->_opnds[0] = op_dst; 11934 m1->_opnds[1] = new immI16Oper(0); 11935 m2->_opnds[0] = op_dst; 11936 m2->_opnds[1] = op_crx; 11937 11938 // registers for new nodes 11939 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11940 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11941 11942 // Insert new nodes. 11943 nodes->push(m1); 11944 nodes->push(m2); 11945 %} 11946%} 11947 11948// Manifest a CmpL3 result in an integer register. Very painful. 11949// This is the test to avoid. 11950// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11951instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11952 match(Set dst (CmpL3 src1 src2)); 11953 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11954 11955 expand %{ 11956 flagsReg tmp1; 11957 cmpL_reg_reg(tmp1, src1, src2); 11958 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11959 %} 11960%} 11961 11962// Implicit range checks. 11963// A range check in the ideal world has one of the following shapes: 11964// - (If le (CmpU length index)), (IfTrue throw exception) 11965// - (If lt (CmpU index length)), (IfFalse throw exception) 11966// 11967// Match range check 'If le (CmpU length index)'. 11968instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11969 match(If cmp (CmpU src_length index)); 11970 effect(USE labl); 11971 predicate(TrapBasedRangeChecks && 11972 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11973 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11974 (Matcher::branches_to_uncommon_trap(_leaf))); 11975 11976 ins_is_TrapBasedCheckNode(true); 11977 11978 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11979 size(4); 11980 ins_encode %{ 11981 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11982 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11983 __ trap_range_check_le($src_length$$Register, $index$$constant); 11984 } else { 11985 // Both successors are uncommon traps, probability is 0. 11986 // Node got flipped during fixup flow. 11987 assert($cmp$$cmpcode == 0x9, "must be greater"); 11988 __ trap_range_check_g($src_length$$Register, $index$$constant); 11989 } 11990 %} 11991 ins_pipe(pipe_class_trap); 11992%} 11993 11994// Match range check 'If lt (CmpU index length)'. 11995instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11996 match(If cmp (CmpU src_index src_length)); 11997 effect(USE labl); 11998 predicate(TrapBasedRangeChecks && 11999 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12000 _leaf->as_If()->_prob >= PROB_ALWAYS && 12001 (Matcher::branches_to_uncommon_trap(_leaf))); 12002 12003 ins_is_TrapBasedCheckNode(true); 12004 12005 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 12006 size(4); 12007 ins_encode %{ 12008 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 12009 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12010 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 12011 } else { 12012 // Both successors are uncommon traps, probability is 0. 12013 // Node got flipped during fixup flow. 12014 assert($cmp$$cmpcode == 0x8, "must be less"); 12015 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 12016 } 12017 %} 12018 ins_pipe(pipe_class_trap); 12019%} 12020 12021// Match range check 'If lt (CmpU index length)'. 12022instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 12023 match(If cmp (CmpU src_index length)); 12024 effect(USE labl); 12025 predicate(TrapBasedRangeChecks && 12026 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 12027 _leaf->as_If()->_prob >= PROB_ALWAYS && 12028 (Matcher::branches_to_uncommon_trap(_leaf))); 12029 12030 ins_is_TrapBasedCheckNode(true); 12031 12032 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 12033 size(4); 12034 ins_encode %{ 12035 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 12036 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 12037 __ trap_range_check_ge($src_index$$Register, $length$$constant); 12038 } else { 12039 // Both successors are uncommon traps, probability is 0. 12040 // Node got flipped during fixup flow. 12041 assert($cmp$$cmpcode == 0x8, "must be less"); 12042 __ trap_range_check_l($src_index$$Register, $length$$constant); 12043 } 12044 %} 12045 ins_pipe(pipe_class_trap); 12046%} 12047 12048instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 12049 match(Set crx (CmpU src1 src2)); 12050 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 12051 size(4); 12052 ins_encode %{ 12053 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12054 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12055 %} 12056 ins_pipe(pipe_class_compare); 12057%} 12058 12059instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 12060 match(Set crx (CmpU src1 src2)); 12061 size(4); 12062 format %{ "CMPLWI $crx, $src1, $src2" %} 12063 ins_encode %{ 12064 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12065 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12066 %} 12067 ins_pipe(pipe_class_compare); 12068%} 12069 12070// Implicit zero checks (more implicit null checks). 12071// No constant pool entries required. 12072instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 12073 match(If cmp (CmpN value zero)); 12074 effect(USE labl); 12075 predicate(TrapBasedNullChecks && 12076 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12077 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12078 Matcher::branches_to_uncommon_trap(_leaf)); 12079 ins_cost(1); 12080 12081 ins_is_TrapBasedCheckNode(true); 12082 12083 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 12084 size(4); 12085 ins_encode %{ 12086 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12087 if ($cmp$$cmpcode == 0xA) { 12088 __ trap_null_check($value$$Register); 12089 } else { 12090 // Both successors are uncommon traps, probability is 0. 12091 // Node got flipped during fixup flow. 12092 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12093 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12094 } 12095 %} 12096 ins_pipe(pipe_class_trap); 12097%} 12098 12099// Compare narrow oops. 12100instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 12101 match(Set crx (CmpN src1 src2)); 12102 12103 size(4); 12104 ins_cost(2); 12105 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 12106 ins_encode %{ 12107 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12108 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 12109 %} 12110 ins_pipe(pipe_class_compare); 12111%} 12112 12113instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 12114 match(Set crx (CmpN src1 src2)); 12115 // Make this more expensive than zeroCheckN_iReg_imm0. 12116 ins_cost(2); 12117 12118 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 12119 size(4); 12120 ins_encode %{ 12121 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 12122 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12123 %} 12124 ins_pipe(pipe_class_compare); 12125%} 12126 12127// Implicit zero checks (more implicit null checks). 12128// No constant pool entries required. 12129instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 12130 match(If cmp (CmpP value zero)); 12131 effect(USE labl); 12132 predicate(TrapBasedNullChecks && 12133 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 12134 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 12135 Matcher::branches_to_uncommon_trap(_leaf)); 12136 ins_cost(1); // Should not be cheaper than zeroCheckN. 12137 12138 ins_is_TrapBasedCheckNode(true); 12139 12140 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 12141 size(4); 12142 ins_encode %{ 12143 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 12144 if ($cmp$$cmpcode == 0xA) { 12145 __ trap_null_check($value$$Register); 12146 } else { 12147 // Both successors are uncommon traps, probability is 0. 12148 // Node got flipped during fixup flow. 12149 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 12150 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 12151 } 12152 %} 12153 ins_pipe(pipe_class_trap); 12154%} 12155 12156// Compare Pointers 12157instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 12158 match(Set crx (CmpP src1 src2)); 12159 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 12160 size(4); 12161 ins_encode %{ 12162 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12163 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 12164 %} 12165 ins_pipe(pipe_class_compare); 12166%} 12167 12168instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 12169 match(Set crx (CmpP src1 src2)); 12170 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 12171 size(4); 12172 ins_encode %{ 12173 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 12174 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 12175 %} 12176 ins_pipe(pipe_class_compare); 12177%} 12178 12179// Used in postalloc expand. 12180instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 12181 // This match rule prevents reordering of node before a safepoint. 12182 // This only makes sense if this instructions is used exclusively 12183 // for the expansion of EncodeP! 12184 match(Set crx (CmpP src1 src2)); 12185 predicate(false); 12186 12187 format %{ "CMPDI $crx, $src1, $src2" %} 12188 size(4); 12189 ins_encode %{ 12190 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 12191 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 12192 %} 12193 ins_pipe(pipe_class_compare); 12194%} 12195 12196//----------Float Compares---------------------------------------------------- 12197 12198instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 12199 // Needs matchrule, see cmpDUnordered. 12200 match(Set crx (CmpF src1 src2)); 12201 // no match-rule, false predicate 12202 predicate(false); 12203 12204 format %{ "cmpFUrd $crx, $src1, $src2" %} 12205 size(4); 12206 ins_encode %{ 12207 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12208 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12209 %} 12210 ins_pipe(pipe_class_default); 12211%} 12212 12213instruct cmov_bns_less(flagsReg crx) %{ 12214 // no match-rule, false predicate 12215 effect(DEF crx); 12216 predicate(false); 12217 12218 ins_variable_size_depending_on_alignment(true); 12219 12220 format %{ "cmov $crx" %} 12221 // Worst case is branch + move + stop, no stop without scheduler. 12222 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 12223 ins_encode %{ 12224 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 12225 Label done; 12226 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 12227 __ li(R0, 0); 12228 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 12229 // TODO PPC port __ endgroup_if_needed(_size == 16); 12230 __ bind(done); 12231 %} 12232 ins_pipe(pipe_class_default); 12233%} 12234 12235// Compare floating, generate condition code. 12236instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 12237 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 12238 // 12239 // The following code sequence occurs a lot in mpegaudio: 12240 // 12241 // block BXX: 12242 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 12243 // cmpFUrd CCR6, F11, F9 12244 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 12245 // cmov CCR6 12246 // 8: instruct branchConSched: 12247 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 12248 match(Set crx (CmpF src1 src2)); 12249 ins_cost(DEFAULT_COST+BRANCH_COST); 12250 12251 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 12252 postalloc_expand %{ 12253 // 12254 // replaces 12255 // 12256 // region src1 src2 12257 // \ | | 12258 // crx=cmpF_reg_reg 12259 // 12260 // with 12261 // 12262 // region src1 src2 12263 // \ | | 12264 // crx=cmpFUnordered_reg_reg 12265 // | 12266 // ^ region 12267 // | \ 12268 // crx=cmov_bns_less 12269 // 12270 12271 // Create new nodes. 12272 MachNode *m1 = new cmpFUnordered_reg_regNode(); 12273 MachNode *m2 = new cmov_bns_lessNode(); 12274 12275 // inputs for new nodes 12276 m1->add_req(n_region, n_src1, n_src2); 12277 m2->add_req(n_region); 12278 m2->add_prec(m1); 12279 12280 // operands for new nodes 12281 m1->_opnds[0] = op_crx; 12282 m1->_opnds[1] = op_src1; 12283 m1->_opnds[2] = op_src2; 12284 m2->_opnds[0] = op_crx; 12285 12286 // registers for new nodes 12287 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12288 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12289 12290 // Insert new nodes. 12291 nodes->push(m1); 12292 nodes->push(m2); 12293 %} 12294%} 12295 12296// Compare float, generate -1,0,1 12297instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 12298 match(Set dst (CmpF3 src1 src2)); 12299 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12300 12301 expand %{ 12302 flagsReg tmp1; 12303 cmpFUnordered_reg_reg(tmp1, src1, src2); 12304 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12305 %} 12306%} 12307 12308instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 12309 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 12310 // node right before the conditional move using it. 12311 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 12312 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 12313 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 12314 // conditional move was supposed to be spilled. 12315 match(Set crx (CmpD src1 src2)); 12316 // False predicate, shall not be matched. 12317 predicate(false); 12318 12319 format %{ "cmpFUrd $crx, $src1, $src2" %} 12320 size(4); 12321 ins_encode %{ 12322 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 12323 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 12324 %} 12325 ins_pipe(pipe_class_default); 12326%} 12327 12328instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 12329 match(Set crx (CmpD src1 src2)); 12330 ins_cost(DEFAULT_COST+BRANCH_COST); 12331 12332 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 12333 postalloc_expand %{ 12334 // 12335 // replaces 12336 // 12337 // region src1 src2 12338 // \ | | 12339 // crx=cmpD_reg_reg 12340 // 12341 // with 12342 // 12343 // region src1 src2 12344 // \ | | 12345 // crx=cmpDUnordered_reg_reg 12346 // | 12347 // ^ region 12348 // | \ 12349 // crx=cmov_bns_less 12350 // 12351 12352 // create new nodes 12353 MachNode *m1 = new cmpDUnordered_reg_regNode(); 12354 MachNode *m2 = new cmov_bns_lessNode(); 12355 12356 // inputs for new nodes 12357 m1->add_req(n_region, n_src1, n_src2); 12358 m2->add_req(n_region); 12359 m2->add_prec(m1); 12360 12361 // operands for new nodes 12362 m1->_opnds[0] = op_crx; 12363 m1->_opnds[1] = op_src1; 12364 m1->_opnds[2] = op_src2; 12365 m2->_opnds[0] = op_crx; 12366 12367 // registers for new nodes 12368 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12369 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 12370 12371 // Insert new nodes. 12372 nodes->push(m1); 12373 nodes->push(m2); 12374 %} 12375%} 12376 12377// Compare double, generate -1,0,1 12378instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 12379 match(Set dst (CmpD3 src1 src2)); 12380 ins_cost(DEFAULT_COST*5+BRANCH_COST); 12381 12382 expand %{ 12383 flagsReg tmp1; 12384 cmpDUnordered_reg_reg(tmp1, src1, src2); 12385 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 12386 %} 12387%} 12388 12389// Compare char 12390instruct cmprb_Digit_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12391 match(Set dst (Digit src1)); 12392 effect(TEMP src2, TEMP crx); 12393 ins_cost(3 * DEFAULT_COST); 12394 12395 format %{ "LI $src2, 0x3930\n\t" 12396 "CMPRB $crx, 0, $src1, $src2\n\t" 12397 "SETB $dst, $crx" %} 12398 size(12); 12399 ins_encode %{ 12400 // 0x30: 0, 0x39: 9 12401 __ li($src2$$Register, 0x3930); 12402 // compare src1 with ranges 0x30 to 0x39 12403 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12404 __ setb($dst$$Register, $crx$$CondRegister); 12405 %} 12406 ins_pipe(pipe_class_default); 12407%} 12408 12409instruct cmprb_LowerCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12410 match(Set dst (LowerCase src1)); 12411 effect(TEMP src2, TEMP crx); 12412 ins_cost(12 * DEFAULT_COST); 12413 12414 format %{ "LI $src2, 0x7A61\n\t" 12415 "CMPRB $crx, 0, $src1, $src2\n\t" 12416 "BGT $crx, done\n\t" 12417 "LIS $src2, (signed short)0xF6DF\n\t" 12418 "ORI $src2, $src2, 0xFFF8\n\t" 12419 "CMPRB $crx, 1, $src1, $src2\n\t" 12420 "BGT $crx, done\n\t" 12421 "LIS $src2, (signed short)0xAAB5\n\t" 12422 "ORI $src2, $src2, 0xBABA\n\t" 12423 "INSRDI $src2, $src2, 32, 0\n\t" 12424 "CMPEQB $crx, 1, $src1, $src2\n" 12425 "done:\n\t" 12426 "SETB $dst, $crx" %} 12427 12428 size(48); 12429 ins_encode %{ 12430 Label done; 12431 // 0x61: a, 0x7A: z 12432 __ li($src2$$Register, 0x7A61); 12433 // compare src1 with ranges 0x61 to 0x7A 12434 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12435 __ bgt($crx$$CondRegister, done); 12436 12437 // 0xDF: sharp s, 0xFF: y with diaeresis, 0xF7 is not the lower case 12438 __ lis($src2$$Register, (signed short)0xF6DF); 12439 __ ori($src2$$Register, $src2$$Register, 0xFFF8); 12440 // compare src1 with ranges 0xDF to 0xF6 and 0xF8 to 0xFF 12441 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12442 __ bgt($crx$$CondRegister, done); 12443 12444 // 0xAA: feminine ordinal indicator 12445 // 0xB5: micro sign 12446 // 0xBA: masculine ordinal indicator 12447 __ lis($src2$$Register, (signed short)0xAAB5); 12448 __ ori($src2$$Register, $src2$$Register, 0xBABA); 12449 __ insrdi($src2$$Register, $src2$$Register, 32, 0); 12450 // compare src1 with 0xAA, 0xB5, and 0xBA 12451 __ cmpeqb($crx$$CondRegister, $src1$$Register, $src2$$Register); 12452 12453 __ bind(done); 12454 __ setb($dst$$Register, $crx$$CondRegister); 12455 %} 12456 ins_pipe(pipe_class_default); 12457%} 12458 12459instruct cmprb_UpperCase_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12460 match(Set dst (UpperCase src1)); 12461 effect(TEMP src2, TEMP crx); 12462 ins_cost(7 * DEFAULT_COST); 12463 12464 format %{ "LI $src2, 0x5A41\n\t" 12465 "CMPRB $crx, 0, $src1, $src2\n\t" 12466 "BGT $crx, done\n\t" 12467 "LIS $src2, (signed short)0xD6C0\n\t" 12468 "ORI $src2, $src2, 0xDED8\n\t" 12469 "CMPRB $crx, 1, $src1, $src2\n" 12470 "done:\n\t" 12471 "SETB $dst, $crx" %} 12472 12473 size(28); 12474 ins_encode %{ 12475 Label done; 12476 // 0x41: A, 0x5A: Z 12477 __ li($src2$$Register, 0x5A41); 12478 // compare src1 with a range 0x41 to 0x5A 12479 __ cmprb($crx$$CondRegister, 0, $src1$$Register, $src2$$Register); 12480 __ bgt($crx$$CondRegister, done); 12481 12482 // 0xC0: a with grave, 0xDE: thorn, 0xD7 is not the upper case 12483 __ lis($src2$$Register, (signed short)0xD6C0); 12484 __ ori($src2$$Register, $src2$$Register, 0xDED8); 12485 // compare src1 with ranges 0xC0 to 0xD6 and 0xD8 to 0xDE 12486 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12487 12488 __ bind(done); 12489 __ setb($dst$$Register, $crx$$CondRegister); 12490 %} 12491 ins_pipe(pipe_class_default); 12492%} 12493 12494instruct cmprb_Whitespace_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsReg crx) %{ 12495 match(Set dst (Whitespace src1)); 12496 effect(TEMP src2, TEMP crx); 12497 ins_cost(4 * DEFAULT_COST); 12498 12499 format %{ "LI $src2, 0x0D09\n\t" 12500 "ADDIS $src2, 0x201C\n\t" 12501 "CMPRB $crx, 1, $src1, $src2\n\t" 12502 "SETB $dst, $crx" %} 12503 size(16); 12504 ins_encode %{ 12505 // 0x09 to 0x0D, 0x1C to 0x20 12506 __ li($src2$$Register, 0x0D09); 12507 __ addis($src2$$Register, $src2$$Register, 0x0201C); 12508 // compare src with ranges 0x09 to 0x0D and 0x1C to 0x20 12509 __ cmprb($crx$$CondRegister, 1, $src1$$Register, $src2$$Register); 12510 __ setb($dst$$Register, $crx$$CondRegister); 12511 %} 12512 ins_pipe(pipe_class_default); 12513%} 12514 12515//----------Branches--------------------------------------------------------- 12516// Jump 12517 12518// Direct Branch. 12519instruct branch(label labl) %{ 12520 match(Goto); 12521 effect(USE labl); 12522 ins_cost(BRANCH_COST); 12523 12524 format %{ "B $labl" %} 12525 size(4); 12526 ins_encode %{ 12527 // TODO: PPC port $archOpcode(ppc64Opcode_b); 12528 Label d; // dummy 12529 __ bind(d); 12530 Label* p = $labl$$label; 12531 // `p' is `NULL' when this encoding class is used only to 12532 // determine the size of the encoded instruction. 12533 Label& l = (NULL == p)? d : *(p); 12534 __ b(l); 12535 %} 12536 ins_pipe(pipe_class_default); 12537%} 12538 12539// Conditional Near Branch 12540instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12541 // Same match rule as `branchConFar'. 12542 match(If cmp crx); 12543 effect(USE lbl); 12544 ins_cost(BRANCH_COST); 12545 12546 // If set to 1 this indicates that the current instruction is a 12547 // short variant of a long branch. This avoids using this 12548 // instruction in first-pass matching. It will then only be used in 12549 // the `Shorten_branches' pass. 12550 ins_short_branch(1); 12551 12552 format %{ "B$cmp $crx, $lbl" %} 12553 size(4); 12554 ins_encode( enc_bc(crx, cmp, lbl) ); 12555 ins_pipe(pipe_class_default); 12556%} 12557 12558// This is for cases when the ppc64 `bc' instruction does not 12559// reach far enough. So we emit a far branch here, which is more 12560// expensive. 12561// 12562// Conditional Far Branch 12563instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12564 // Same match rule as `branchCon'. 12565 match(If cmp crx); 12566 effect(USE crx, USE lbl); 12567 predicate(!false /* TODO: PPC port HB_Schedule*/); 12568 // Higher cost than `branchCon'. 12569 ins_cost(5*BRANCH_COST); 12570 12571 // This is not a short variant of a branch, but the long variant. 12572 ins_short_branch(0); 12573 12574 format %{ "B_FAR$cmp $crx, $lbl" %} 12575 size(8); 12576 ins_encode( enc_bc_far(crx, cmp, lbl) ); 12577 ins_pipe(pipe_class_default); 12578%} 12579 12580// Conditional Branch used with Power6 scheduler (can be far or short). 12581instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 12582 // Same match rule as `branchCon'. 12583 match(If cmp crx); 12584 effect(USE crx, USE lbl); 12585 predicate(false /* TODO: PPC port HB_Schedule*/); 12586 // Higher cost than `branchCon'. 12587 ins_cost(5*BRANCH_COST); 12588 12589 // Actually size doesn't depend on alignment but on shortening. 12590 ins_variable_size_depending_on_alignment(true); 12591 // long variant. 12592 ins_short_branch(0); 12593 12594 format %{ "B_FAR$cmp $crx, $lbl" %} 12595 size(8); // worst case 12596 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 12597 ins_pipe(pipe_class_default); 12598%} 12599 12600instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12601 match(CountedLoopEnd cmp crx); 12602 effect(USE labl); 12603 ins_cost(BRANCH_COST); 12604 12605 // short variant. 12606 ins_short_branch(1); 12607 12608 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 12609 size(4); 12610 ins_encode( enc_bc(crx, cmp, labl) ); 12611 ins_pipe(pipe_class_default); 12612%} 12613 12614instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12615 match(CountedLoopEnd cmp crx); 12616 effect(USE labl); 12617 predicate(!false /* TODO: PPC port HB_Schedule */); 12618 ins_cost(BRANCH_COST); 12619 12620 // Long variant. 12621 ins_short_branch(0); 12622 12623 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12624 size(8); 12625 ins_encode( enc_bc_far(crx, cmp, labl) ); 12626 ins_pipe(pipe_class_default); 12627%} 12628 12629// Conditional Branch used with Power6 scheduler (can be far or short). 12630instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 12631 match(CountedLoopEnd cmp crx); 12632 effect(USE labl); 12633 predicate(false /* TODO: PPC port HB_Schedule */); 12634 // Higher cost than `branchCon'. 12635 ins_cost(5*BRANCH_COST); 12636 12637 // Actually size doesn't depend on alignment but on shortening. 12638 ins_variable_size_depending_on_alignment(true); 12639 // Long variant. 12640 ins_short_branch(0); 12641 12642 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 12643 size(8); // worst case 12644 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 12645 ins_pipe(pipe_class_default); 12646%} 12647 12648// ============================================================================ 12649// Java runtime operations, intrinsics and other complex operations. 12650 12651// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12652// array for an instance of the superklass. Set a hidden internal cache on a 12653// hit (cache is checked with exposed code in gen_subtype_check()). Return 12654// not zero for a miss or zero for a hit. The encoding ALSO sets flags. 12655// 12656// GL TODO: Improve this. 12657// - result should not be a TEMP 12658// - Add match rule as on sparc avoiding additional Cmp. 12659instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 12660 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 12661 match(Set result (PartialSubtypeCheck subklass superklass)); 12662 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 12663 ins_cost(DEFAULT_COST*10); 12664 12665 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 12666 ins_encode %{ 12667 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12668 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 12669 $tmp_klass$$Register, NULL, $result$$Register); 12670 %} 12671 ins_pipe(pipe_class_default); 12672%} 12673 12674// inlined locking and unlocking 12675 12676instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 12677 match(Set crx (FastLock oop box)); 12678 effect(TEMP tmp1, TEMP tmp2); 12679 predicate(!Compile::current()->use_rtm()); 12680 12681 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 12682 ins_encode %{ 12683 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12684 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12685 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 12686 UseBiasedLocking && !UseOptoBiasInlining); 12687 // If locking was successfull, crx should indicate 'EQ'. 12688 // The compiler generates a branch to the runtime call to 12689 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12690 %} 12691 ins_pipe(pipe_class_compare); 12692%} 12693 12694// Separate version for TM. Use bound register for box to enable USE_KILL. 12695instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12696 match(Set crx (FastLock oop box)); 12697 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 12698 predicate(Compile::current()->use_rtm()); 12699 12700 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 12701 ins_encode %{ 12702 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12703 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12704 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12705 /*Biased Locking*/ false, 12706 _rtm_counters, _stack_rtm_counters, 12707 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12708 /*TM*/ true, ra_->C->profile_rtm()); 12709 // If locking was successfull, crx should indicate 'EQ'. 12710 // The compiler generates a branch to the runtime call to 12711 // _complete_monitor_locking_Java for the case where crx is 'NE'. 12712 %} 12713 ins_pipe(pipe_class_compare); 12714%} 12715 12716instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12717 match(Set crx (FastUnlock oop box)); 12718 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12719 predicate(!Compile::current()->use_rtm()); 12720 12721 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 12722 ins_encode %{ 12723 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12724 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12725 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12726 UseBiasedLocking && !UseOptoBiasInlining, 12727 false); 12728 // If unlocking was successfull, crx should indicate 'EQ'. 12729 // The compiler generates a branch to the runtime call to 12730 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12731 %} 12732 ins_pipe(pipe_class_compare); 12733%} 12734 12735instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 12736 match(Set crx (FastUnlock oop box)); 12737 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 12738 predicate(Compile::current()->use_rtm()); 12739 12740 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 12741 ins_encode %{ 12742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12743 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 12744 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12745 /*Biased Locking*/ false, /*TM*/ true); 12746 // If unlocking was successfull, crx should indicate 'EQ'. 12747 // The compiler generates a branch to the runtime call to 12748 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 12749 %} 12750 ins_pipe(pipe_class_compare); 12751%} 12752 12753// Align address. 12754instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 12755 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 12756 12757 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 12758 size(4); 12759 ins_encode %{ 12760 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 12761 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 12762 %} 12763 ins_pipe(pipe_class_default); 12764%} 12765 12766// Array size computation. 12767instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 12768 match(Set dst (SubL (CastP2X end) (CastP2X start))); 12769 12770 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 12771 size(4); 12772 ins_encode %{ 12773 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 12774 __ subf($dst$$Register, $start$$Register, $end$$Register); 12775 %} 12776 ins_pipe(pipe_class_default); 12777%} 12778 12779// Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 12780instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12781 match(Set dummy (ClearArray cnt base)); 12782 effect(USE_KILL base, KILL ctr); 12783 ins_cost(2 * MEMORY_REF_COST); 12784 12785 format %{ "ClearArray $cnt, $base" %} 12786 ins_encode %{ 12787 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12788 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 12789 %} 12790 ins_pipe(pipe_class_default); 12791%} 12792 12793// Clear-array with constant large array length. 12794instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 12795 match(Set dummy (ClearArray cnt base)); 12796 effect(USE_KILL base, TEMP tmp, KILL ctr); 12797 ins_cost(3 * MEMORY_REF_COST); 12798 12799 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 12800 ins_encode %{ 12801 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12802 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 12803 %} 12804 ins_pipe(pipe_class_default); 12805%} 12806 12807// Clear-array with dynamic array length. 12808instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 12809 match(Set dummy (ClearArray cnt base)); 12810 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 12811 ins_cost(4 * MEMORY_REF_COST); 12812 12813 format %{ "ClearArray $cnt, $base" %} 12814 ins_encode %{ 12815 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12816 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 12817 %} 12818 ins_pipe(pipe_class_default); 12819%} 12820 12821instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12822 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12823 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12824 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12825 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12826 ins_cost(300); 12827 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12828 ins_encode %{ 12829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12830 __ string_compare($str1$$Register, $str2$$Register, 12831 $cnt1$$Register, $cnt2$$Register, 12832 $tmp$$Register, 12833 $result$$Register, StrIntrinsicNode::LL); 12834 %} 12835 ins_pipe(pipe_class_default); 12836%} 12837 12838instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12839 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12840 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12841 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12842 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12843 ins_cost(300); 12844 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12845 ins_encode %{ 12846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12847 __ string_compare($str1$$Register, $str2$$Register, 12848 $cnt1$$Register, $cnt2$$Register, 12849 $tmp$$Register, 12850 $result$$Register, StrIntrinsicNode::UU); 12851 %} 12852 ins_pipe(pipe_class_default); 12853%} 12854 12855instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12856 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12857 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12858 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12859 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12860 ins_cost(300); 12861 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12862 ins_encode %{ 12863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12864 __ string_compare($str1$$Register, $str2$$Register, 12865 $cnt1$$Register, $cnt2$$Register, 12866 $tmp$$Register, 12867 $result$$Register, StrIntrinsicNode::LU); 12868 %} 12869 ins_pipe(pipe_class_default); 12870%} 12871 12872instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12873 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12874 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12875 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12876 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12877 ins_cost(300); 12878 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12879 ins_encode %{ 12880 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12881 __ string_compare($str2$$Register, $str1$$Register, 12882 $cnt2$$Register, $cnt1$$Register, 12883 $tmp$$Register, 12884 $result$$Register, StrIntrinsicNode::UL); 12885 %} 12886 ins_pipe(pipe_class_default); 12887%} 12888 12889instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12890 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12891 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12892 match(Set result (StrEquals (Binary str1 str2) cnt)); 12893 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12894 ins_cost(300); 12895 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12896 ins_encode %{ 12897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12898 __ array_equals(false, $str1$$Register, $str2$$Register, 12899 $cnt$$Register, $tmp$$Register, 12900 $result$$Register, true /* byte */); 12901 %} 12902 ins_pipe(pipe_class_default); 12903%} 12904 12905instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12906 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12907 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12908 match(Set result (StrEquals (Binary str1 str2) cnt)); 12909 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12910 ins_cost(300); 12911 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12912 ins_encode %{ 12913 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12914 __ array_equals(false, $str1$$Register, $str2$$Register, 12915 $cnt$$Register, $tmp$$Register, 12916 $result$$Register, false /* byte */); 12917 %} 12918 ins_pipe(pipe_class_default); 12919%} 12920 12921instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12922 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12923 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12924 match(Set result (AryEq ary1 ary2)); 12925 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12926 ins_cost(300); 12927 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12928 ins_encode %{ 12929 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12930 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12931 $tmp1$$Register, $tmp2$$Register, 12932 $result$$Register, true /* byte */); 12933 %} 12934 ins_pipe(pipe_class_default); 12935%} 12936 12937instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12938 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12939 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12940 match(Set result (AryEq ary1 ary2)); 12941 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12942 ins_cost(300); 12943 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12944 ins_encode %{ 12945 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12946 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12947 $tmp1$$Register, $tmp2$$Register, 12948 $result$$Register, false /* byte */); 12949 %} 12950 ins_pipe(pipe_class_default); 12951%} 12952 12953instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12954 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12955 iRegIdst tmp1, iRegIdst tmp2, 12956 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12957 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12958 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12959 // Required for EA: check if it is still a type_array. 12960 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12961 ins_cost(150); 12962 12963 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12964 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12965 12966 ins_encode %{ 12967 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12968 immPOper *needleOper = (immPOper *)$needleImm; 12969 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12970 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12971 jchar chr; 12972#ifdef VM_LITTLE_ENDIAN 12973 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12974 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12975#else 12976 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12977 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12978#endif 12979 __ string_indexof_char($result$$Register, 12980 $haystack$$Register, $haycnt$$Register, 12981 R0, chr, 12982 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12983 %} 12984 ins_pipe(pipe_class_compare); 12985%} 12986 12987instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12988 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12989 iRegIdst tmp1, iRegIdst tmp2, 12990 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12991 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12992 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12993 // Required for EA: check if it is still a type_array. 12994 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12995 ins_cost(150); 12996 12997 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12998 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12999 13000 ins_encode %{ 13001 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13002 immPOper *needleOper = (immPOper *)$needleImm; 13003 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13004 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13005 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13006 __ string_indexof_char($result$$Register, 13007 $haystack$$Register, $haycnt$$Register, 13008 R0, chr, 13009 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13010 %} 13011 ins_pipe(pipe_class_compare); 13012%} 13013 13014instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13015 immP needleImm, immL offsetImm, immI_1 needlecntImm, 13016 iRegIdst tmp1, iRegIdst tmp2, 13017 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13018 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 13019 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13020 // Required for EA: check if it is still a type_array. 13021 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13022 ins_cost(150); 13023 13024 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 13025 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13026 13027 ins_encode %{ 13028 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13029 immPOper *needleOper = (immPOper *)$needleImm; 13030 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 13031 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 13032 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13033 __ string_indexof_char($result$$Register, 13034 $haystack$$Register, $haycnt$$Register, 13035 R0, chr, 13036 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13037 %} 13038 ins_pipe(pipe_class_compare); 13039%} 13040 13041instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13042 rscratch2RegP needle, immI_1 needlecntImm, 13043 iRegIdst tmp1, iRegIdst tmp2, 13044 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13045 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13046 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13047 // Required for EA: check if it is still a type_array. 13048 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13049 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13050 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13051 ins_cost(180); 13052 13053 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13054 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13055 ins_encode %{ 13056 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13057 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13058 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13059 guarantee(needle_values, "sanity"); 13060 jchar chr; 13061#ifdef VM_LITTLE_ENDIAN 13062 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 13063 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 13064#else 13065 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 13066 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 13067#endif 13068 __ string_indexof_char($result$$Register, 13069 $haystack$$Register, $haycnt$$Register, 13070 R0, chr, 13071 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13072 %} 13073 ins_pipe(pipe_class_compare); 13074%} 13075 13076instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13077 rscratch2RegP needle, immI_1 needlecntImm, 13078 iRegIdst tmp1, iRegIdst tmp2, 13079 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13080 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13081 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13082 // Required for EA: check if it is still a type_array. 13083 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13084 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13085 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13086 ins_cost(180); 13087 13088 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13089 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13090 ins_encode %{ 13091 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13092 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13093 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13094 guarantee(needle_values, "sanity"); 13095 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13096 __ string_indexof_char($result$$Register, 13097 $haystack$$Register, $haycnt$$Register, 13098 R0, chr, 13099 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 13100 %} 13101 ins_pipe(pipe_class_compare); 13102%} 13103 13104instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13105 rscratch2RegP needle, immI_1 needlecntImm, 13106 iRegIdst tmp1, iRegIdst tmp2, 13107 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13108 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13109 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13110 // Required for EA: check if it is still a type_array. 13111 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13112 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13113 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13114 ins_cost(180); 13115 13116 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13117 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 13118 ins_encode %{ 13119 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13120 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13121 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13122 guarantee(needle_values, "sanity"); 13123 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 13124 __ string_indexof_char($result$$Register, 13125 $haystack$$Register, $haycnt$$Register, 13126 R0, chr, 13127 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13128 %} 13129 ins_pipe(pipe_class_compare); 13130%} 13131 13132instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 13133 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 13134 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 13135 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 13136 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 13137 ins_cost(180); 13138 13139 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 13140 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 13141 ins_encode %{ 13142 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13143 __ string_indexof_char($result$$Register, 13144 $haystack$$Register, $haycnt$$Register, 13145 $ch$$Register, 0 /* this is not used if the character is already in a register */, 13146 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 13147 %} 13148 ins_pipe(pipe_class_compare); 13149%} 13150 13151instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13152 iRegPsrc needle, uimmI15 needlecntImm, 13153 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13154 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13155 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13156 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13157 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13158 // Required for EA: check if it is still a type_array. 13159 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 13160 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13161 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13162 ins_cost(250); 13163 13164 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13165 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13166 ins_encode %{ 13167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13168 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13169 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13170 13171 __ string_indexof($result$$Register, 13172 $haystack$$Register, $haycnt$$Register, 13173 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13174 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13175 %} 13176 ins_pipe(pipe_class_compare); 13177%} 13178 13179instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13180 iRegPsrc needle, uimmI15 needlecntImm, 13181 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13182 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13183 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13184 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13185 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13186 // Required for EA: check if it is still a type_array. 13187 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 13188 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13189 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13190 ins_cost(250); 13191 13192 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13193 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13194 ins_encode %{ 13195 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13196 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13197 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13198 13199 __ string_indexof($result$$Register, 13200 $haystack$$Register, $haycnt$$Register, 13201 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13202 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13203 %} 13204 ins_pipe(pipe_class_compare); 13205%} 13206 13207instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 13208 iRegPsrc needle, uimmI15 needlecntImm, 13209 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 13210 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13211 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 13212 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 13213 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13214 // Required for EA: check if it is still a type_array. 13215 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 13216 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 13217 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 13218 ins_cost(250); 13219 13220 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 13221 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 13222 ins_encode %{ 13223 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13224 Node *ndl = in(operand_index($needle)); // The node that defines needle. 13225 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 13226 13227 __ string_indexof($result$$Register, 13228 $haystack$$Register, $haycnt$$Register, 13229 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 13230 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13231 %} 13232 ins_pipe(pipe_class_compare); 13233%} 13234 13235instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13236 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13237 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13238 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13239 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13240 TEMP_DEF result, 13241 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13242 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 13243 ins_cost(300); 13244 13245 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13246 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13247 ins_encode %{ 13248 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13249 __ string_indexof($result$$Register, 13250 $haystack$$Register, $haycnt$$Register, 13251 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13252 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 13253 %} 13254 ins_pipe(pipe_class_compare); 13255%} 13256 13257instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13258 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13259 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13260 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13261 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13262 TEMP_DEF result, 13263 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13264 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 13265 ins_cost(300); 13266 13267 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13268 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13269 ins_encode %{ 13270 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13271 __ string_indexof($result$$Register, 13272 $haystack$$Register, $haycnt$$Register, 13273 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13274 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 13275 %} 13276 ins_pipe(pipe_class_compare); 13277%} 13278 13279instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 13280 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 13281 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 13282 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 13283 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 13284 TEMP_DEF result, 13285 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 13286 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 13287 ins_cost(300); 13288 13289 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 13290 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 13291 ins_encode %{ 13292 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13293 __ string_indexof($result$$Register, 13294 $haystack$$Register, $haycnt$$Register, 13295 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 13296 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 13297 %} 13298 ins_pipe(pipe_class_compare); 13299%} 13300 13301// char[] to byte[] compression 13302instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13303 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13304 match(Set result (StrCompressedCopy src (Binary dst len))); 13305 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13306 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13307 ins_cost(300); 13308 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13309 ins_encode %{ 13310 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13311 Label Lskip, Ldone; 13312 __ li($result$$Register, 0); 13313 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13314 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 13315 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13316 __ beq(CCR0, Lskip); 13317 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 13318 __ bind(Lskip); 13319 __ mr($result$$Register, $len$$Register); 13320 __ bind(Ldone); 13321 %} 13322 ins_pipe(pipe_class_default); 13323%} 13324 13325// byte[] to char[] inflation 13326instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 13327 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13328 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13329 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13330 ins_cost(300); 13331 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13332 ins_encode %{ 13333 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13334 Label Ldone; 13335 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13336 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 13337 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13338 __ beq(CCR0, Ldone); 13339 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 13340 __ bind(Ldone); 13341 %} 13342 ins_pipe(pipe_class_default); 13343%} 13344 13345// StringCoding.java intrinsics 13346instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 13347 regCTR ctr, flagsRegCR0 cr0) 13348%{ 13349 match(Set result (HasNegatives ary1 len)); 13350 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 13351 ins_cost(300); 13352 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 13353 ins_encode %{ 13354 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13355 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 13356 $tmp1$$Register, $tmp2$$Register); 13357 %} 13358 ins_pipe(pipe_class_default); 13359%} 13360 13361// encode char[] to byte[] in ISO_8859_1 13362instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 13363 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 13364 match(Set result (EncodeISOArray src (Binary dst len))); 13365 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 13366 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 13367 ins_cost(300); 13368 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 13369 ins_encode %{ 13370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13371 Label Lslow, Lfailure1, Lfailure2, Ldone; 13372 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 13373 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 13374 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 13375 __ beq(CCR0, Ldone); 13376 __ bind(Lslow); 13377 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 13378 __ li($result$$Register, 0); 13379 __ b(Ldone); 13380 13381 __ bind(Lfailure1); 13382 __ mr($result$$Register, $len$$Register); 13383 __ mfctr($tmp1$$Register); 13384 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 13385 __ beq(CCR0, Ldone); 13386 __ b(Lslow); 13387 13388 __ bind(Lfailure2); 13389 __ mfctr($result$$Register); // Remaining characters. 13390 13391 __ bind(Ldone); 13392 __ subf($result$$Register, $result$$Register, $len$$Register); 13393 %} 13394 ins_pipe(pipe_class_default); 13395%} 13396 13397 13398//---------- Min/Max Instructions --------------------------------------------- 13399 13400instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13401 match(Set dst (MinI src1 src2)); 13402 ins_cost(DEFAULT_COST*6); 13403 13404 expand %{ 13405 iRegLdst src1s; 13406 iRegLdst src2s; 13407 iRegLdst diff; 13408 iRegLdst sm; 13409 iRegLdst doz; // difference or zero 13410 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13411 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13412 subL_reg_reg(diff, src2s, src1s); 13413 // Need to consider >=33 bit result, therefore we need signmaskL. 13414 signmask64L_regL(sm, diff); 13415 andL_reg_reg(doz, diff, sm); // <=0 13416 addI_regL_regL(dst, doz, src1s); 13417 %} 13418%} 13419 13420instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13421 match(Set dst (MinI src1 src2)); 13422 effect(KILL cr0); 13423 predicate(VM_Version::has_isel()); 13424 ins_cost(DEFAULT_COST*2); 13425 13426 ins_encode %{ 13427 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13428 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13429 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 13430 %} 13431 ins_pipe(pipe_class_default); 13432%} 13433 13434instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 13435 match(Set dst (MaxI src1 src2)); 13436 ins_cost(DEFAULT_COST*6); 13437 13438 expand %{ 13439 iRegLdst src1s; 13440 iRegLdst src2s; 13441 iRegLdst diff; 13442 iRegLdst sm; 13443 iRegLdst doz; // difference or zero 13444 convI2L_reg(src1s, src1); // Ensure proper sign extension. 13445 convI2L_reg(src2s, src2); // Ensure proper sign extension. 13446 subL_reg_reg(diff, src2s, src1s); 13447 // Need to consider >=33 bit result, therefore we need signmaskL. 13448 signmask64L_regL(sm, diff); 13449 andcL_reg_reg(doz, diff, sm); // >=0 13450 addI_regL_regL(dst, doz, src1s); 13451 %} 13452%} 13453 13454instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 13455 match(Set dst (MaxI src1 src2)); 13456 effect(KILL cr0); 13457 predicate(VM_Version::has_isel()); 13458 ins_cost(DEFAULT_COST*2); 13459 13460 ins_encode %{ 13461 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13462 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 13463 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 13464 %} 13465 ins_pipe(pipe_class_default); 13466%} 13467 13468//---------- Population Count Instructions ------------------------------------ 13469 13470// Popcnt for Power7. 13471instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 13472 match(Set dst (PopCountI src)); 13473 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13474 ins_cost(DEFAULT_COST); 13475 13476 format %{ "POPCNTW $dst, $src" %} 13477 size(4); 13478 ins_encode %{ 13479 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13480 __ popcntw($dst$$Register, $src$$Register); 13481 %} 13482 ins_pipe(pipe_class_default); 13483%} 13484 13485// Popcnt for Power7. 13486instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 13487 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 13488 match(Set dst (PopCountL src)); 13489 ins_cost(DEFAULT_COST); 13490 13491 format %{ "POPCNTD $dst, $src" %} 13492 size(4); 13493 ins_encode %{ 13494 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 13495 __ popcntd($dst$$Register, $src$$Register); 13496 %} 13497 ins_pipe(pipe_class_default); 13498%} 13499 13500instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 13501 match(Set dst (CountLeadingZerosI src)); 13502 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13503 ins_cost(DEFAULT_COST); 13504 13505 format %{ "CNTLZW $dst, $src" %} 13506 size(4); 13507 ins_encode %{ 13508 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 13509 __ cntlzw($dst$$Register, $src$$Register); 13510 %} 13511 ins_pipe(pipe_class_default); 13512%} 13513 13514instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 13515 match(Set dst (CountLeadingZerosL src)); 13516 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 13517 ins_cost(DEFAULT_COST); 13518 13519 format %{ "CNTLZD $dst, $src" %} 13520 size(4); 13521 ins_encode %{ 13522 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13523 __ cntlzd($dst$$Register, $src$$Register); 13524 %} 13525 ins_pipe(pipe_class_default); 13526%} 13527 13528instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 13529 // no match-rule, false predicate 13530 effect(DEF dst, USE src); 13531 predicate(false); 13532 13533 format %{ "CNTLZD $dst, $src" %} 13534 size(4); 13535 ins_encode %{ 13536 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 13537 __ cntlzd($dst$$Register, $src$$Register); 13538 %} 13539 ins_pipe(pipe_class_default); 13540%} 13541 13542instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 13543 match(Set dst (CountTrailingZerosI src)); 13544 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13545 ins_cost(DEFAULT_COST); 13546 13547 expand %{ 13548 immI16 imm1 %{ (int)-1 %} 13549 immI16 imm2 %{ (int)32 %} 13550 immI_minus1 m1 %{ -1 %} 13551 iRegIdst tmpI1; 13552 iRegIdst tmpI2; 13553 iRegIdst tmpI3; 13554 addI_reg_imm16(tmpI1, src, imm1); 13555 andcI_reg_reg(tmpI2, src, m1, tmpI1); 13556 countLeadingZerosI(tmpI3, tmpI2); 13557 subI_imm16_reg(dst, imm2, tmpI3); 13558 %} 13559%} 13560 13561instruct countTrailingZerosI_cnttzw(iRegIdst dst, iRegIsrc src) %{ 13562 match(Set dst (CountTrailingZerosI src)); 13563 predicate(UseCountTrailingZerosInstructionsPPC64); 13564 ins_cost(DEFAULT_COST); 13565 13566 format %{ "CNTTZW $dst, $src" %} 13567 size(4); 13568 ins_encode %{ 13569 __ cnttzw($dst$$Register, $src$$Register); 13570 %} 13571 ins_pipe(pipe_class_default); 13572%} 13573 13574instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 13575 match(Set dst (CountTrailingZerosL src)); 13576 predicate(UseCountLeadingZerosInstructionsPPC64 && !UseCountTrailingZerosInstructionsPPC64); 13577 ins_cost(DEFAULT_COST); 13578 13579 expand %{ 13580 immL16 imm1 %{ (long)-1 %} 13581 immI16 imm2 %{ (int)64 %} 13582 iRegLdst tmpL1; 13583 iRegLdst tmpL2; 13584 iRegIdst tmpL3; 13585 addL_reg_imm16(tmpL1, src, imm1); 13586 andcL_reg_reg(tmpL2, tmpL1, src); 13587 countLeadingZerosL(tmpL3, tmpL2); 13588 subI_imm16_reg(dst, imm2, tmpL3); 13589 %} 13590%} 13591 13592instruct countTrailingZerosL_cnttzd(iRegIdst dst, iRegLsrc src) %{ 13593 match(Set dst (CountTrailingZerosL src)); 13594 predicate(UseCountTrailingZerosInstructionsPPC64); 13595 ins_cost(DEFAULT_COST); 13596 13597 format %{ "CNTTZD $dst, $src" %} 13598 size(4); 13599 ins_encode %{ 13600 __ cnttzd($dst$$Register, $src$$Register); 13601 %} 13602 ins_pipe(pipe_class_default); 13603%} 13604 13605// Expand nodes for byte_reverse_int. 13606instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13607 effect(DEF dst, USE src, USE pos, USE shift); 13608 predicate(false); 13609 13610 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13611 size(4); 13612 ins_encode %{ 13613 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13614 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13615 %} 13616 ins_pipe(pipe_class_default); 13617%} 13618 13619// As insrwi_a, but with USE_DEF. 13620instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 13621 effect(USE_DEF dst, USE src, USE pos, USE shift); 13622 predicate(false); 13623 13624 format %{ "INSRWI $dst, $src, $pos, $shift" %} 13625 size(4); 13626 ins_encode %{ 13627 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 13628 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 13629 %} 13630 ins_pipe(pipe_class_default); 13631%} 13632 13633// Just slightly faster than java implementation. 13634instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 13635 match(Set dst (ReverseBytesI src)); 13636 predicate(!UseByteReverseInstructions); 13637 ins_cost(7*DEFAULT_COST); 13638 13639 expand %{ 13640 immI16 imm24 %{ (int) 24 %} 13641 immI16 imm16 %{ (int) 16 %} 13642 immI16 imm8 %{ (int) 8 %} 13643 immI16 imm4 %{ (int) 4 %} 13644 immI16 imm0 %{ (int) 0 %} 13645 iRegLdst tmpI1; 13646 iRegLdst tmpI2; 13647 iRegLdst tmpI3; 13648 13649 urShiftI_reg_imm(tmpI1, src, imm24); 13650 insrwi_a(dst, tmpI1, imm24, imm8); 13651 urShiftI_reg_imm(tmpI2, src, imm16); 13652 insrwi(dst, tmpI2, imm8, imm16); 13653 urShiftI_reg_imm(tmpI3, src, imm8); 13654 insrwi(dst, tmpI3, imm8, imm8); 13655 insrwi(dst, src, imm0, imm8); 13656 %} 13657%} 13658 13659instruct bytes_reverse_int(iRegIdst dst, iRegIsrc src) %{ 13660 match(Set dst (ReverseBytesI src)); 13661 predicate(UseByteReverseInstructions); 13662 ins_cost(DEFAULT_COST); 13663 size(4); 13664 13665 format %{ "BRW $dst, $src" %} 13666 13667 ins_encode %{ 13668 __ brw($dst$$Register, $src$$Register); 13669 %} 13670 ins_pipe(pipe_class_default); 13671%} 13672 13673instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 13674 match(Set dst (ReverseBytesL src)); 13675 predicate(!UseByteReverseInstructions); 13676 ins_cost(15*DEFAULT_COST); 13677 13678 expand %{ 13679 immI16 imm56 %{ (int) 56 %} 13680 immI16 imm48 %{ (int) 48 %} 13681 immI16 imm40 %{ (int) 40 %} 13682 immI16 imm32 %{ (int) 32 %} 13683 immI16 imm24 %{ (int) 24 %} 13684 immI16 imm16 %{ (int) 16 %} 13685 immI16 imm8 %{ (int) 8 %} 13686 immI16 imm0 %{ (int) 0 %} 13687 iRegLdst tmpL1; 13688 iRegLdst tmpL2; 13689 iRegLdst tmpL3; 13690 iRegLdst tmpL4; 13691 iRegLdst tmpL5; 13692 iRegLdst tmpL6; 13693 13694 // src : |a|b|c|d|e|f|g|h| 13695 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 13696 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 13697 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 13698 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 13699 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 13700 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 13701 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 13702 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 13703 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 13704 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 13705 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 13706 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 13707 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 13708 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 13709 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 13710 %} 13711%} 13712 13713instruct bytes_reverse_long(iRegLdst dst, iRegLsrc src) %{ 13714 match(Set dst (ReverseBytesL src)); 13715 predicate(UseByteReverseInstructions); 13716 ins_cost(DEFAULT_COST); 13717 size(4); 13718 13719 format %{ "BRD $dst, $src" %} 13720 13721 ins_encode %{ 13722 __ brd($dst$$Register, $src$$Register); 13723 %} 13724 ins_pipe(pipe_class_default); 13725%} 13726 13727instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 13728 match(Set dst (ReverseBytesUS src)); 13729 predicate(!UseByteReverseInstructions); 13730 ins_cost(2*DEFAULT_COST); 13731 13732 expand %{ 13733 immI16 imm16 %{ (int) 16 %} 13734 immI16 imm8 %{ (int) 8 %} 13735 13736 urShiftI_reg_imm(dst, src, imm8); 13737 insrwi(dst, src, imm16, imm8); 13738 %} 13739%} 13740 13741instruct bytes_reverse_ushort(iRegIdst dst, iRegIsrc src) %{ 13742 match(Set dst (ReverseBytesUS src)); 13743 predicate(UseByteReverseInstructions); 13744 ins_cost(DEFAULT_COST); 13745 size(4); 13746 13747 format %{ "BRH $dst, $src" %} 13748 13749 ins_encode %{ 13750 __ brh($dst$$Register, $src$$Register); 13751 %} 13752 ins_pipe(pipe_class_default); 13753%} 13754 13755instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 13756 match(Set dst (ReverseBytesS src)); 13757 predicate(!UseByteReverseInstructions); 13758 ins_cost(3*DEFAULT_COST); 13759 13760 expand %{ 13761 immI16 imm16 %{ (int) 16 %} 13762 immI16 imm8 %{ (int) 8 %} 13763 iRegLdst tmpI1; 13764 13765 urShiftI_reg_imm(tmpI1, src, imm8); 13766 insrwi(tmpI1, src, imm16, imm8); 13767 extsh(dst, tmpI1); 13768 %} 13769%} 13770 13771instruct bytes_reverse_short(iRegIdst dst, iRegIsrc src) %{ 13772 match(Set dst (ReverseBytesS src)); 13773 predicate(UseByteReverseInstructions); 13774 ins_cost(DEFAULT_COST); 13775 size(8); 13776 13777 format %{ "BRH $dst, $src\n\t" 13778 "EXTSH $dst, $dst" %} 13779 13780 ins_encode %{ 13781 __ brh($dst$$Register, $src$$Register); 13782 __ extsh($dst$$Register, $dst$$Register); 13783 %} 13784 ins_pipe(pipe_class_default); 13785%} 13786 13787// Load Integer reversed byte order 13788instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 13789 match(Set dst (ReverseBytesI (LoadI mem))); 13790 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13791 ins_cost(MEMORY_REF_COST); 13792 13793 size(4); 13794 ins_encode %{ 13795 __ lwbrx($dst$$Register, $mem$$Register); 13796 %} 13797 ins_pipe(pipe_class_default); 13798%} 13799 13800instruct loadI_reversed_acquire(iRegIdst dst, indirect mem) %{ 13801 match(Set dst (ReverseBytesI (LoadI mem))); 13802 ins_cost(2 * MEMORY_REF_COST); 13803 13804 size(12); 13805 ins_encode %{ 13806 __ lwbrx($dst$$Register, $mem$$Register); 13807 __ twi_0($dst$$Register); 13808 __ isync(); 13809 %} 13810 ins_pipe(pipe_class_default); 13811%} 13812 13813// Load Long - aligned and reversed 13814instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 13815 match(Set dst (ReverseBytesL (LoadL mem))); 13816 predicate(VM_Version::has_ldbrx() && (n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1)))); 13817 ins_cost(MEMORY_REF_COST); 13818 13819 size(4); 13820 ins_encode %{ 13821 __ ldbrx($dst$$Register, $mem$$Register); 13822 %} 13823 ins_pipe(pipe_class_default); 13824%} 13825 13826instruct loadL_reversed_acquire(iRegLdst dst, indirect mem) %{ 13827 match(Set dst (ReverseBytesL (LoadL mem))); 13828 predicate(VM_Version::has_ldbrx()); 13829 ins_cost(2 * MEMORY_REF_COST); 13830 13831 size(12); 13832 ins_encode %{ 13833 __ ldbrx($dst$$Register, $mem$$Register); 13834 __ twi_0($dst$$Register); 13835 __ isync(); 13836 %} 13837 ins_pipe(pipe_class_default); 13838%} 13839 13840// Load unsigned short / char reversed byte order 13841instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 13842 match(Set dst (ReverseBytesUS (LoadUS mem))); 13843 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13844 ins_cost(MEMORY_REF_COST); 13845 13846 size(4); 13847 ins_encode %{ 13848 __ lhbrx($dst$$Register, $mem$$Register); 13849 %} 13850 ins_pipe(pipe_class_default); 13851%} 13852 13853instruct loadUS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13854 match(Set dst (ReverseBytesUS (LoadUS mem))); 13855 ins_cost(2 * MEMORY_REF_COST); 13856 13857 size(12); 13858 ins_encode %{ 13859 __ lhbrx($dst$$Register, $mem$$Register); 13860 __ twi_0($dst$$Register); 13861 __ isync(); 13862 %} 13863 ins_pipe(pipe_class_default); 13864%} 13865 13866// Load short reversed byte order 13867instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 13868 match(Set dst (ReverseBytesS (LoadS mem))); 13869 predicate(n->in(1)->as_Load()->is_unordered() || followed_by_acquire(n->in(1))); 13870 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 13871 13872 size(8); 13873 ins_encode %{ 13874 __ lhbrx($dst$$Register, $mem$$Register); 13875 __ extsh($dst$$Register, $dst$$Register); 13876 %} 13877 ins_pipe(pipe_class_default); 13878%} 13879 13880instruct loadS_reversed_acquire(iRegIdst dst, indirect mem) %{ 13881 match(Set dst (ReverseBytesS (LoadS mem))); 13882 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13883 13884 size(16); 13885 ins_encode %{ 13886 __ lhbrx($dst$$Register, $mem$$Register); 13887 __ twi_0($dst$$Register); 13888 __ extsh($dst$$Register, $dst$$Register); 13889 __ isync(); 13890 %} 13891 ins_pipe(pipe_class_default); 13892%} 13893 13894// Store Integer reversed byte order 13895instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 13896 match(Set mem (StoreI mem (ReverseBytesI src))); 13897 ins_cost(MEMORY_REF_COST); 13898 13899 size(4); 13900 ins_encode %{ 13901 __ stwbrx($src$$Register, $mem$$Register); 13902 %} 13903 ins_pipe(pipe_class_default); 13904%} 13905 13906// Store Long reversed byte order 13907instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 13908 match(Set mem (StoreL mem (ReverseBytesL src))); 13909 predicate(VM_Version::has_stdbrx()); 13910 ins_cost(MEMORY_REF_COST); 13911 13912 size(4); 13913 ins_encode %{ 13914 __ stdbrx($src$$Register, $mem$$Register); 13915 %} 13916 ins_pipe(pipe_class_default); 13917%} 13918 13919// Store unsigned short / char reversed byte order 13920instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 13921 match(Set mem (StoreC mem (ReverseBytesUS src))); 13922 ins_cost(MEMORY_REF_COST); 13923 13924 size(4); 13925 ins_encode %{ 13926 __ sthbrx($src$$Register, $mem$$Register); 13927 %} 13928 ins_pipe(pipe_class_default); 13929%} 13930 13931// Store short reversed byte order 13932instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 13933 match(Set mem (StoreC mem (ReverseBytesS src))); 13934 ins_cost(MEMORY_REF_COST); 13935 13936 size(4); 13937 ins_encode %{ 13938 __ sthbrx($src$$Register, $mem$$Register); 13939 %} 13940 ins_pipe(pipe_class_default); 13941%} 13942 13943instruct mtvsrwz(vecX temp1, iRegIsrc src) %{ 13944 effect(DEF temp1, USE src); 13945 13946 size(4); 13947 ins_encode %{ 13948 __ mtvsrwz($temp1$$VectorSRegister, $src$$Register); 13949 %} 13950 ins_pipe(pipe_class_default); 13951%} 13952 13953instruct xxspltw(vecX dst, vecX src, immI8 imm1) %{ 13954 effect(DEF dst, USE src, USE imm1); 13955 13956 size(4); 13957 ins_encode %{ 13958 __ xxspltw($dst$$VectorSRegister, $src$$VectorSRegister, $imm1$$constant); 13959 %} 13960 ins_pipe(pipe_class_default); 13961%} 13962 13963//---------- Replicate Vector Instructions ------------------------------------ 13964 13965// Insrdi does replicate if src == dst. 13966instruct repl32(iRegLdst dst) %{ 13967 predicate(false); 13968 effect(USE_DEF dst); 13969 13970 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 13971 size(4); 13972 ins_encode %{ 13973 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13974 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 13975 %} 13976 ins_pipe(pipe_class_default); 13977%} 13978 13979// Insrdi does replicate if src == dst. 13980instruct repl48(iRegLdst dst) %{ 13981 predicate(false); 13982 effect(USE_DEF dst); 13983 13984 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 13985 size(4); 13986 ins_encode %{ 13987 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 13988 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 13989 %} 13990 ins_pipe(pipe_class_default); 13991%} 13992 13993// Insrdi does replicate if src == dst. 13994instruct repl56(iRegLdst dst) %{ 13995 predicate(false); 13996 effect(USE_DEF dst); 13997 13998 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 13999 size(4); 14000 ins_encode %{ 14001 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 14002 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 14003 %} 14004 ins_pipe(pipe_class_default); 14005%} 14006 14007instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14008 match(Set dst (ReplicateB src)); 14009 predicate(n->as_Vector()->length() == 8); 14010 expand %{ 14011 moveReg(dst, src); 14012 repl56(dst); 14013 repl48(dst); 14014 repl32(dst); 14015 %} 14016%} 14017 14018instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 14019 match(Set dst (ReplicateB zero)); 14020 predicate(n->as_Vector()->length() == 8); 14021 format %{ "LI $dst, #0 \t// replicate8B" %} 14022 size(4); 14023 ins_encode %{ 14024 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14025 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14026 %} 14027 ins_pipe(pipe_class_default); 14028%} 14029 14030instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14031 match(Set dst (ReplicateB src)); 14032 predicate(n->as_Vector()->length() == 8); 14033 format %{ "LI $dst, #-1 \t// replicate8B" %} 14034 size(4); 14035 ins_encode %{ 14036 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14037 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14038 %} 14039 ins_pipe(pipe_class_default); 14040%} 14041 14042instruct repl16B_reg_Ex(vecX dst, iRegIsrc src) %{ 14043 match(Set dst (ReplicateB src)); 14044 predicate(n->as_Vector()->length() == 16); 14045 14046 expand %{ 14047 iRegLdst tmpL; 14048 vecX tmpV; 14049 immI8 imm1 %{ (int) 1 %} 14050 moveReg(tmpL, src); 14051 repl56(tmpL); 14052 repl48(tmpL); 14053 mtvsrwz(tmpV, tmpL); 14054 xxspltw(dst, tmpV, imm1); 14055 %} 14056%} 14057 14058instruct repl16B_immI0(vecX dst, immI_0 zero) %{ 14059 match(Set dst (ReplicateB zero)); 14060 predicate(n->as_Vector()->length() == 16); 14061 14062 format %{ "XXLXOR $dst, $zero \t// replicate16B" %} 14063 size(4); 14064 ins_encode %{ 14065 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14066 %} 14067 ins_pipe(pipe_class_default); 14068%} 14069 14070instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ 14071 match(Set dst (ReplicateB src)); 14072 predicate(n->as_Vector()->length() == 16); 14073 14074 format %{ "XXLEQV $dst, $src \t// replicate16B" %} 14075 size(4); 14076 ins_encode %{ 14077 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14078 %} 14079 ins_pipe(pipe_class_default); 14080%} 14081 14082instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14083 match(Set dst (ReplicateS src)); 14084 predicate(n->as_Vector()->length() == 4); 14085 expand %{ 14086 moveReg(dst, src); 14087 repl48(dst); 14088 repl32(dst); 14089 %} 14090%} 14091 14092instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 14093 match(Set dst (ReplicateS zero)); 14094 predicate(n->as_Vector()->length() == 4); 14095 format %{ "LI $dst, #0 \t// replicate4S" %} 14096 size(4); 14097 ins_encode %{ 14098 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14099 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14100 %} 14101 ins_pipe(pipe_class_default); 14102%} 14103 14104instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14105 match(Set dst (ReplicateS src)); 14106 predicate(n->as_Vector()->length() == 4); 14107 format %{ "LI $dst, -1 \t// replicate4S" %} 14108 size(4); 14109 ins_encode %{ 14110 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14111 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14112 %} 14113 ins_pipe(pipe_class_default); 14114%} 14115 14116instruct repl8S_reg_Ex(vecX dst, iRegIsrc src) %{ 14117 match(Set dst (ReplicateS src)); 14118 predicate(n->as_Vector()->length() == 8); 14119 14120 expand %{ 14121 iRegLdst tmpL; 14122 vecX tmpV; 14123 immI8 zero %{ (int) 0 %} 14124 moveReg(tmpL, src); 14125 repl48(tmpL); 14126 repl32(tmpL); 14127 mtvsrd(tmpV, tmpL); 14128 xxpermdi(dst, tmpV, tmpV, zero); 14129 %} 14130%} 14131 14132instruct repl8S_immI0(vecX dst, immI_0 zero) %{ 14133 match(Set dst (ReplicateS zero)); 14134 predicate(n->as_Vector()->length() == 8); 14135 14136 format %{ "XXLXOR $dst, $zero \t// replicate8S" %} 14137 size(4); 14138 ins_encode %{ 14139 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14140 %} 14141 ins_pipe(pipe_class_default); 14142%} 14143 14144instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ 14145 match(Set dst (ReplicateS src)); 14146 predicate(n->as_Vector()->length() == 8); 14147 14148 format %{ "XXLEQV $dst, $src \t// replicate8S" %} 14149 size(4); 14150 ins_encode %{ 14151 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14152 %} 14153 ins_pipe(pipe_class_default); 14154%} 14155 14156instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 14157 match(Set dst (ReplicateI src)); 14158 predicate(n->as_Vector()->length() == 2); 14159 ins_cost(2 * DEFAULT_COST); 14160 expand %{ 14161 moveReg(dst, src); 14162 repl32(dst); 14163 %} 14164%} 14165 14166instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 14167 match(Set dst (ReplicateI zero)); 14168 predicate(n->as_Vector()->length() == 2); 14169 format %{ "LI $dst, #0 \t// replicate2I" %} 14170 size(4); 14171 ins_encode %{ 14172 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14173 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 14174 %} 14175 ins_pipe(pipe_class_default); 14176%} 14177 14178instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 14179 match(Set dst (ReplicateI src)); 14180 predicate(n->as_Vector()->length() == 2); 14181 format %{ "LI $dst, -1 \t// replicate2I" %} 14182 size(4); 14183 ins_encode %{ 14184 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14185 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 14186 %} 14187 ins_pipe(pipe_class_default); 14188%} 14189 14190instruct repl4I_reg_Ex(vecX dst, iRegIsrc src) %{ 14191 match(Set dst (ReplicateI src)); 14192 predicate(n->as_Vector()->length() == 4); 14193 ins_cost(2 * DEFAULT_COST); 14194 14195 expand %{ 14196 iRegLdst tmpL; 14197 vecX tmpV; 14198 immI8 zero %{ (int) 0 %} 14199 moveReg(tmpL, src); 14200 repl32(tmpL); 14201 mtvsrd(tmpV, tmpL); 14202 xxpermdi(dst, tmpV, tmpV, zero); 14203 %} 14204%} 14205 14206instruct repl4I_immI0(vecX dst, immI_0 zero) %{ 14207 match(Set dst (ReplicateI zero)); 14208 predicate(n->as_Vector()->length() == 4); 14209 14210 format %{ "XXLXOR $dst, $zero \t// replicate4I" %} 14211 size(4); 14212 ins_encode %{ 14213 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14214 %} 14215 ins_pipe(pipe_class_default); 14216%} 14217 14218instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ 14219 match(Set dst (ReplicateI src)); 14220 predicate(n->as_Vector()->length() == 4); 14221 14222 format %{ "XXLEQV $dst, $dst, $dst \t// replicate4I" %} 14223 size(4); 14224 ins_encode %{ 14225 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14226 %} 14227 ins_pipe(pipe_class_default); 14228%} 14229 14230// Move float to int register via stack, replicate. 14231instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 14232 match(Set dst (ReplicateF src)); 14233 predicate(n->as_Vector()->length() == 2); 14234 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14235 expand %{ 14236 stackSlotL tmpS; 14237 iRegIdst tmpI; 14238 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14239 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14240 moveReg(dst, tmpI); // Move int to long reg. 14241 repl32(dst); // Replicate bitpattern. 14242 %} 14243%} 14244 14245// Replicate scalar constant to packed float values in Double register 14246instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 14247 match(Set dst (ReplicateF src)); 14248 predicate(n->as_Vector()->length() == 2); 14249 ins_cost(5 * DEFAULT_COST); 14250 14251 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 14252 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 14253%} 14254 14255// Replicate scalar zero constant to packed float values in Double register 14256instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 14257 match(Set dst (ReplicateF zero)); 14258 predicate(n->as_Vector()->length() == 2); 14259 14260 format %{ "LI $dst, #0 \t// replicate2F" %} 14261 ins_encode %{ 14262 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 14263 __ li($dst$$Register, 0x0); 14264 %} 14265 ins_pipe(pipe_class_default); 14266%} 14267 14268 14269//----------Overflow Math Instructions----------------------------------------- 14270 14271// Note that we have to make sure that XER.SO is reset before using overflow instructions. 14272// Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 14273// Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 14274 14275instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14276 match(Set cr0 (OverflowAddL op1 op2)); 14277 14278 format %{ "add_ $op1, $op2\t# overflow check long" %} 14279 ins_encode %{ 14280 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14281 __ li(R0, 0); 14282 __ mtxer(R0); // clear XER.SO 14283 __ addo_(R0, $op1$$Register, $op2$$Register); 14284 %} 14285 ins_pipe(pipe_class_default); 14286%} 14287 14288instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14289 match(Set cr0 (OverflowSubL op1 op2)); 14290 14291 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 14292 ins_encode %{ 14293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14294 __ li(R0, 0); 14295 __ mtxer(R0); // clear XER.SO 14296 __ subfo_(R0, $op2$$Register, $op1$$Register); 14297 %} 14298 ins_pipe(pipe_class_default); 14299%} 14300 14301instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 14302 match(Set cr0 (OverflowSubL zero op2)); 14303 14304 format %{ "nego_ R0, $op2\t# overflow check long" %} 14305 ins_encode %{ 14306 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14307 __ li(R0, 0); 14308 __ mtxer(R0); // clear XER.SO 14309 __ nego_(R0, $op2$$Register); 14310 %} 14311 ins_pipe(pipe_class_default); 14312%} 14313 14314instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 14315 match(Set cr0 (OverflowMulL op1 op2)); 14316 14317 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 14318 ins_encode %{ 14319 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14320 __ li(R0, 0); 14321 __ mtxer(R0); // clear XER.SO 14322 __ mulldo_(R0, $op1$$Register, $op2$$Register); 14323 %} 14324 ins_pipe(pipe_class_default); 14325%} 14326 14327 14328instruct repl4F_reg_Ex(vecX dst, regF src) %{ 14329 match(Set dst (ReplicateF src)); 14330 predicate(n->as_Vector()->length() == 4); 14331 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 14332 expand %{ 14333 stackSlotL tmpS; 14334 iRegIdst tmpI; 14335 iRegLdst tmpL; 14336 vecX tmpV; 14337 immI8 zero %{ (int) 0 %} 14338 14339 moveF2I_reg_stack(tmpS, src); // Move float to stack. 14340 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 14341 moveReg(tmpL, tmpI); // Move int to long reg. 14342 repl32(tmpL); // Replicate bitpattern. 14343 mtvsrd(tmpV, tmpL); 14344 xxpermdi(dst, tmpV, tmpV, zero); 14345 %} 14346%} 14347 14348instruct repl4F_immF_Ex(vecX dst, immF src, iRegLdst tmp) %{ 14349 match(Set dst (ReplicateF src)); 14350 predicate(n->as_Vector()->length() == 4); 14351 effect(TEMP tmp); 14352 ins_cost(10 * DEFAULT_COST); 14353 14354 postalloc_expand( postalloc_expand_load_replF_constant_vsx(dst, src, constanttablebase, tmp) ); 14355%} 14356 14357instruct repl4F_immF0(vecX dst, immF_0 zero) %{ 14358 match(Set dst (ReplicateF zero)); 14359 predicate(n->as_Vector()->length() == 4); 14360 14361 format %{ "XXLXOR $dst, $zero \t// replicate4F" %} 14362 ins_encode %{ 14363 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14364 %} 14365 ins_pipe(pipe_class_default); 14366%} 14367 14368instruct repl2D_reg_Ex(vecX dst, regD src) %{ 14369 match(Set dst (ReplicateD src)); 14370 predicate(n->as_Vector()->length() == 2); 14371 expand %{ 14372 stackSlotL tmpS; 14373 iRegLdst tmpL; 14374 iRegLdst tmp; 14375 vecX tmpV; 14376 immI8 zero %{ (int) 0 %} 14377 moveD2L_reg_stack(tmpS, src); 14378 moveD2L_stack_reg(tmpL, tmpS); 14379 mtvsrd(tmpV, tmpL); 14380 xxpermdi(dst, tmpV, tmpV, zero); 14381 %} 14382%} 14383 14384instruct repl2D_immD0(vecX dst, immD_0 zero) %{ 14385 match(Set dst (ReplicateD zero)); 14386 predicate(n->as_Vector()->length() == 2); 14387 14388 format %{ "XXLXOR $dst, $zero \t// replicate2D" %} 14389 size(4); 14390 ins_encode %{ 14391 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14392 %} 14393 ins_pipe(pipe_class_default); 14394%} 14395 14396instruct mtvsrd(vecX dst, iRegLsrc src) %{ 14397 predicate(false); 14398 effect(DEF dst, USE src); 14399 14400 format %{ "MTVSRD $dst, $src \t// Move to 16-byte register"%} 14401 size(4); 14402 ins_encode %{ 14403 __ mtvsrd($dst$$VectorSRegister, $src$$Register); 14404 %} 14405 ins_pipe(pipe_class_default); 14406%} 14407 14408instruct xxspltd(vecX dst, vecX src, immI8 zero) %{ 14409 effect(DEF dst, USE src, USE zero); 14410 14411 format %{ "XXSPLATD $dst, $src, $zero \t// Permute 16-byte register"%} 14412 size(4); 14413 ins_encode %{ 14414 __ xxpermdi($dst$$VectorSRegister, $src$$VectorSRegister, $src$$VectorSRegister, $zero$$constant); 14415 %} 14416 ins_pipe(pipe_class_default); 14417%} 14418 14419instruct xxpermdi(vecX dst, vecX src1, vecX src2, immI8 zero) %{ 14420 effect(DEF dst, USE src1, USE src2, USE zero); 14421 14422 format %{ "XXPERMDI $dst, $src1, $src2, $zero \t// Permute 16-byte register"%} 14423 size(4); 14424 ins_encode %{ 14425 __ xxpermdi($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister, $zero$$constant); 14426 %} 14427 ins_pipe(pipe_class_default); 14428%} 14429 14430instruct repl2L_reg_Ex(vecX dst, iRegLsrc src) %{ 14431 match(Set dst (ReplicateL src)); 14432 predicate(n->as_Vector()->length() == 2); 14433 expand %{ 14434 vecX tmpV; 14435 immI8 zero %{ (int) 0 %} 14436 mtvsrd(tmpV, src); 14437 xxpermdi(dst, tmpV, tmpV, zero); 14438 %} 14439%} 14440 14441instruct repl2L_immI0(vecX dst, immI_0 zero) %{ 14442 match(Set dst (ReplicateL zero)); 14443 predicate(n->as_Vector()->length() == 2); 14444 14445 format %{ "XXLXOR $dst, $zero \t// replicate2L" %} 14446 size(4); 14447 ins_encode %{ 14448 __ xxlxor($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14449 %} 14450 ins_pipe(pipe_class_default); 14451%} 14452 14453instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ 14454 match(Set dst (ReplicateL src)); 14455 predicate(n->as_Vector()->length() == 2); 14456 14457 format %{ "XXLEQV $dst, $src \t// replicate2L" %} 14458 size(4); 14459 ins_encode %{ 14460 __ xxleqv($dst$$VectorSRegister, $dst$$VectorSRegister, $dst$$VectorSRegister); 14461 %} 14462 ins_pipe(pipe_class_default); 14463%} 14464 14465// ============================================================================ 14466// Safepoint Instruction 14467 14468instruct safePoint_poll(iRegPdst poll) %{ 14469 match(SafePoint poll); 14470 14471 // It caused problems to add the effect that r0 is killed, but this 14472 // effect no longer needs to be mentioned, since r0 is not contained 14473 // in a reg_class. 14474 14475 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 14476 size(4); 14477 ins_encode( enc_poll(0x0, poll) ); 14478 ins_pipe(pipe_class_default); 14479%} 14480 14481// ============================================================================ 14482// Call Instructions 14483 14484// Call Java Static Instruction 14485 14486// Schedulable version of call static node. 14487instruct CallStaticJavaDirect(method meth) %{ 14488 match(CallStaticJava); 14489 effect(USE meth); 14490 ins_cost(CALL_COST); 14491 14492 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 14493 14494 format %{ "CALL,static $meth \t// ==> " %} 14495 size(4); 14496 ins_encode( enc_java_static_call(meth) ); 14497 ins_pipe(pipe_class_call); 14498%} 14499 14500// Call Java Dynamic Instruction 14501 14502// Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 14503// Loading of IC was postalloc expanded. The nodes loading the IC are reachable 14504// via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 14505// The call destination must still be placed in the constant pool. 14506instruct CallDynamicJavaDirectSched(method meth) %{ 14507 match(CallDynamicJava); // To get all the data fields we need ... 14508 effect(USE meth); 14509 predicate(false); // ... but never match. 14510 14511 ins_field_load_ic_hi_node(loadConL_hiNode*); 14512 ins_field_load_ic_node(loadConLNode*); 14513 ins_num_consts(1 /* 1 patchable constant: call destination */); 14514 14515 format %{ "BL \t// dynamic $meth ==> " %} 14516 size(4); 14517 ins_encode( enc_java_dynamic_call_sched(meth) ); 14518 ins_pipe(pipe_class_call); 14519%} 14520 14521// Schedulable (i.e. postalloc expanded) version of call dynamic java. 14522// We use postalloc expanded calls if we use inline caches 14523// and do not update method data. 14524// 14525// This instruction has two constants: inline cache (IC) and call destination. 14526// Loading the inline cache will be postalloc expanded, thus leaving a call with 14527// one constant. 14528instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 14529 match(CallDynamicJava); 14530 effect(USE meth); 14531 predicate(UseInlineCaches); 14532 ins_cost(CALL_COST); 14533 14534 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 14535 14536 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 14537 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 14538%} 14539 14540// Compound version of call dynamic java 14541// We use postalloc expanded calls if we use inline caches 14542// and do not update method data. 14543instruct CallDynamicJavaDirect(method meth) %{ 14544 match(CallDynamicJava); 14545 effect(USE meth); 14546 predicate(!UseInlineCaches); 14547 ins_cost(CALL_COST); 14548 14549 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 14550 ins_num_consts(4); 14551 14552 format %{ "CALL,dynamic $meth \t// ==> " %} 14553 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 14554 ins_pipe(pipe_class_call); 14555%} 14556 14557// Call Runtime Instruction 14558 14559instruct CallRuntimeDirect(method meth) %{ 14560 match(CallRuntime); 14561 effect(USE meth); 14562 ins_cost(CALL_COST); 14563 14564 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14565 // env for callee, C-toc. 14566 ins_num_consts(3); 14567 14568 format %{ "CALL,runtime" %} 14569 ins_encode( enc_java_to_runtime_call(meth) ); 14570 ins_pipe(pipe_class_call); 14571%} 14572 14573// Call Leaf 14574 14575// Used by postalloc expand of CallLeafDirect_Ex (mtctr). 14576instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 14577 effect(DEF dst, USE src); 14578 14579 ins_num_consts(1); 14580 14581 format %{ "MTCTR $src" %} 14582 size(4); 14583 ins_encode( enc_leaf_call_mtctr(src) ); 14584 ins_pipe(pipe_class_default); 14585%} 14586 14587// Used by postalloc expand of CallLeafDirect_Ex (actual call). 14588instruct CallLeafDirect(method meth) %{ 14589 match(CallLeaf); // To get the data all the data fields we need ... 14590 effect(USE meth); 14591 predicate(false); // but never match. 14592 14593 format %{ "BCTRL \t// leaf call $meth ==> " %} 14594 size(4); 14595 ins_encode %{ 14596 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 14597 __ bctrl(); 14598 %} 14599 ins_pipe(pipe_class_call); 14600%} 14601 14602// postalloc expand of CallLeafDirect. 14603// Load adress to call from TOC, then bl to it. 14604instruct CallLeafDirect_Ex(method meth) %{ 14605 match(CallLeaf); 14606 effect(USE meth); 14607 ins_cost(CALL_COST); 14608 14609 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 14610 // env for callee, C-toc. 14611 ins_num_consts(3); 14612 14613 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 14614 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14615%} 14616 14617// Call runtime without safepoint - same as CallLeaf. 14618// postalloc expand of CallLeafNoFPDirect. 14619// Load adress to call from TOC, then bl to it. 14620instruct CallLeafNoFPDirect_Ex(method meth) %{ 14621 match(CallLeafNoFP); 14622 effect(USE meth); 14623 ins_cost(CALL_COST); 14624 14625 // Enc_java_to_runtime_call needs up to 3 constants: call target, 14626 // env for callee, C-toc. 14627 ins_num_consts(3); 14628 14629 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 14630 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 14631%} 14632 14633// Tail Call; Jump from runtime stub to Java code. 14634// Also known as an 'interprocedural jump'. 14635// Target of jump will eventually return to caller. 14636// TailJump below removes the return address. 14637instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 14638 match(TailCall jump_target method_oop); 14639 ins_cost(CALL_COST); 14640 14641 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 14642 "BCTR \t// tail call" %} 14643 size(8); 14644 ins_encode %{ 14645 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14646 __ mtctr($jump_target$$Register); 14647 __ bctr(); 14648 %} 14649 ins_pipe(pipe_class_call); 14650%} 14651 14652// Return Instruction 14653instruct Ret() %{ 14654 match(Return); 14655 format %{ "BLR \t// branch to link register" %} 14656 size(4); 14657 ins_encode %{ 14658 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 14659 // LR is restored in MachEpilogNode. Just do the RET here. 14660 __ blr(); 14661 %} 14662 ins_pipe(pipe_class_default); 14663%} 14664 14665// Tail Jump; remove the return address; jump to target. 14666// TailCall above leaves the return address around. 14667// TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 14668// ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 14669// "restore" before this instruction (in Epilogue), we need to materialize it 14670// in %i0. 14671instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 14672 match(TailJump jump_target ex_oop); 14673 ins_cost(CALL_COST); 14674 14675 format %{ "LD R4_ARG2 = LR\n\t" 14676 "MTCTR $jump_target\n\t" 14677 "BCTR \t// TailJump, exception oop: $ex_oop" %} 14678 size(12); 14679 ins_encode %{ 14680 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14681 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 14682 __ mtctr($jump_target$$Register); 14683 __ bctr(); 14684 %} 14685 ins_pipe(pipe_class_call); 14686%} 14687 14688// Create exception oop: created by stack-crawling runtime code. 14689// Created exception is now available to this handler, and is setup 14690// just prior to jumping to this handler. No code emitted. 14691instruct CreateException(rarg1RegP ex_oop) %{ 14692 match(Set ex_oop (CreateEx)); 14693 ins_cost(0); 14694 14695 format %{ " -- \t// exception oop; no code emitted" %} 14696 size(0); 14697 ins_encode( /*empty*/ ); 14698 ins_pipe(pipe_class_default); 14699%} 14700 14701// Rethrow exception: The exception oop will come in the first 14702// argument position. Then JUMP (not call) to the rethrow stub code. 14703instruct RethrowException() %{ 14704 match(Rethrow); 14705 ins_cost(CALL_COST); 14706 14707 format %{ "Jmp rethrow_stub" %} 14708 ins_encode %{ 14709 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 14710 cbuf.set_insts_mark(); 14711 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 14712 %} 14713 ins_pipe(pipe_class_call); 14714%} 14715 14716// Die now. 14717instruct ShouldNotReachHere() %{ 14718 match(Halt); 14719 ins_cost(CALL_COST); 14720 14721 format %{ "ShouldNotReachHere" %} 14722 ins_encode %{ 14723 if (is_reachable()) { 14724 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 14725 __ trap_should_not_reach_here(); 14726 } 14727 %} 14728 ins_pipe(pipe_class_default); 14729%} 14730 14731// This name is KNOWN by the ADLC and cannot be changed. The ADLC 14732// forces a 'TypeRawPtr::BOTTOM' output type for this guy. 14733// Get a DEF on threadRegP, no costs, no encoding, use 14734// 'ins_should_rematerialize(true)' to avoid spilling. 14735instruct tlsLoadP(threadRegP dst) %{ 14736 match(Set dst (ThreadLocal)); 14737 ins_cost(0); 14738 14739 ins_should_rematerialize(true); 14740 14741 format %{ " -- \t// $dst=Thread::current(), empty" %} 14742 size(0); 14743 ins_encode( /*empty*/ ); 14744 ins_pipe(pipe_class_empty); 14745%} 14746 14747//---Some PPC specific nodes--------------------------------------------------- 14748 14749// Stop a group. 14750instruct endGroup() %{ 14751 ins_cost(0); 14752 14753 ins_is_nop(true); 14754 14755 format %{ "End Bundle (ori r1, r1, 0)" %} 14756 size(4); 14757 ins_encode %{ 14758 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 14759 __ endgroup(); 14760 %} 14761 ins_pipe(pipe_class_default); 14762%} 14763 14764// Nop instructions 14765 14766instruct fxNop() %{ 14767 ins_cost(0); 14768 14769 ins_is_nop(true); 14770 14771 format %{ "fxNop" %} 14772 size(4); 14773 ins_encode %{ 14774 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14775 __ nop(); 14776 %} 14777 ins_pipe(pipe_class_default); 14778%} 14779 14780instruct fpNop0() %{ 14781 ins_cost(0); 14782 14783 ins_is_nop(true); 14784 14785 format %{ "fpNop0" %} 14786 size(4); 14787 ins_encode %{ 14788 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14789 __ fpnop0(); 14790 %} 14791 ins_pipe(pipe_class_default); 14792%} 14793 14794instruct fpNop1() %{ 14795 ins_cost(0); 14796 14797 ins_is_nop(true); 14798 14799 format %{ "fpNop1" %} 14800 size(4); 14801 ins_encode %{ 14802 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 14803 __ fpnop1(); 14804 %} 14805 ins_pipe(pipe_class_default); 14806%} 14807 14808instruct brNop0() %{ 14809 ins_cost(0); 14810 size(4); 14811 format %{ "brNop0" %} 14812 ins_encode %{ 14813 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14814 __ brnop0(); 14815 %} 14816 ins_is_nop(true); 14817 ins_pipe(pipe_class_default); 14818%} 14819 14820instruct brNop1() %{ 14821 ins_cost(0); 14822 14823 ins_is_nop(true); 14824 14825 format %{ "brNop1" %} 14826 size(4); 14827 ins_encode %{ 14828 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14829 __ brnop1(); 14830 %} 14831 ins_pipe(pipe_class_default); 14832%} 14833 14834instruct brNop2() %{ 14835 ins_cost(0); 14836 14837 ins_is_nop(true); 14838 14839 format %{ "brNop2" %} 14840 size(4); 14841 ins_encode %{ 14842 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 14843 __ brnop2(); 14844 %} 14845 ins_pipe(pipe_class_default); 14846%} 14847 14848//----------PEEPHOLE RULES----------------------------------------------------- 14849// These must follow all instruction definitions as they use the names 14850// defined in the instructions definitions. 14851// 14852// peepmatch ( root_instr_name [preceeding_instruction]* ); 14853// 14854// peepconstraint %{ 14855// (instruction_number.operand_name relational_op instruction_number.operand_name 14856// [, ...] ); 14857// // instruction numbers are zero-based using left to right order in peepmatch 14858// 14859// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14860// // provide an instruction_number.operand_name for each operand that appears 14861// // in the replacement instruction's match rule 14862// 14863// ---------VM FLAGS--------------------------------------------------------- 14864// 14865// All peephole optimizations can be turned off using -XX:-OptoPeephole 14866// 14867// Each peephole rule is given an identifying number starting with zero and 14868// increasing by one in the order seen by the parser. An individual peephole 14869// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14870// on the command-line. 14871// 14872// ---------CURRENT LIMITATIONS---------------------------------------------- 14873// 14874// Only match adjacent instructions in same basic block 14875// Only equality constraints 14876// Only constraints between operands, not (0.dest_reg == EAX_enc) 14877// Only one replacement instruction 14878// 14879// ---------EXAMPLE---------------------------------------------------------- 14880// 14881// // pertinent parts of existing instructions in architecture description 14882// instruct movI(eRegI dst, eRegI src) %{ 14883// match(Set dst (CopyI src)); 14884// %} 14885// 14886// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14887// match(Set dst (AddI dst src)); 14888// effect(KILL cr); 14889// %} 14890// 14891// // Change (inc mov) to lea 14892// peephole %{ 14893// // increment preceeded by register-register move 14894// peepmatch ( incI_eReg movI ); 14895// // require that the destination register of the increment 14896// // match the destination register of the move 14897// peepconstraint ( 0.dst == 1.dst ); 14898// // construct a replacement instruction that sets 14899// // the destination to ( move's source register + one ) 14900// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14901// %} 14902// 14903// Implementation no longer uses movX instructions since 14904// machine-independent system no longer uses CopyX nodes. 14905// 14906// peephole %{ 14907// peepmatch ( incI_eReg movI ); 14908// peepconstraint ( 0.dst == 1.dst ); 14909// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14910// %} 14911// 14912// peephole %{ 14913// peepmatch ( decI_eReg movI ); 14914// peepconstraint ( 0.dst == 1.dst ); 14915// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14916// %} 14917// 14918// peephole %{ 14919// peepmatch ( addI_eReg_imm movI ); 14920// peepconstraint ( 0.dst == 1.dst ); 14921// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14922// %} 14923// 14924// peephole %{ 14925// peepmatch ( addP_eReg_imm movP ); 14926// peepconstraint ( 0.dst == 1.dst ); 14927// peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14928// %} 14929 14930// // Change load of spilled value to only a spill 14931// instruct storeI(memory mem, eRegI src) %{ 14932// match(Set mem (StoreI mem src)); 14933// %} 14934// 14935// instruct loadI(eRegI dst, memory mem) %{ 14936// match(Set dst (LoadI mem)); 14937// %} 14938// 14939peephole %{ 14940 peepmatch ( loadI storeI ); 14941 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14942 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14943%} 14944 14945peephole %{ 14946 peepmatch ( loadL storeL ); 14947 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14948 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 14949%} 14950 14951peephole %{ 14952 peepmatch ( loadP storeP ); 14953 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 14954 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 14955%} 14956 14957//----------SMARTSPILL RULES--------------------------------------------------- 14958// These must follow all instruction definitions as they use the names 14959// defined in the instructions definitions. 14960