1 // 2 // Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. 4 // Copyright (c) 2020, 2024, Huawei Technologies Co., Ltd. All rights reserved. 5 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 // 7 // This code is free software; you can redistribute it and/or modify it 8 // under the terms of the GNU General Public License version 2 only, as 9 // published by the Free Software Foundation. 10 // 11 // This code is distributed in the hope that it will be useful, but WITHOUT 12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 // version 2 for more details (a copy is included in the LICENSE file that 15 // accompanied this code). 16 // 17 // You should have received a copy of the GNU General Public License version 18 // 2 along with this work; if not, write to the Free Software Foundation, 19 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 // 21 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 // or visit www.oracle.com if you need additional information or have any 23 // questions. 24 // 25 // 26 27 // RISCV Architecture Description File 28 29 //----------REGISTER DEFINITION BLOCK------------------------------------------ 30 // This information is used by the matcher and the register allocator to 31 // describe individual registers and classes of registers within the target 32 // architecture. 33 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name ( register save type, C convention save type, 38 // ideal register type, encoding ); 39 // Register Save Types: 40 // 41 // NS = No-Save: The register allocator assumes that these registers 42 // can be used without saving upon entry to the method, & 43 // that they do not need to be saved at call sites. 44 // 45 // SOC = Save-On-Call: The register allocator assumes that these registers 46 // can be used without saving upon entry to the method, 47 // but that they must be saved at call sites. 48 // 49 // SOE = Save-On-Entry: The register allocator assumes that these registers 50 // must be saved before using them upon entry to the 51 // method, but they do not need to be saved at call 52 // sites. 53 // 54 // AS = Always-Save: The register allocator assumes that these registers 55 // must be saved before using them upon entry to the 56 // method, & that they must be saved at call sites. 57 // 58 // Ideal Register Type is used to determine how to save & restore a 59 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 60 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 61 // 62 // The encoding number is the actual bit-pattern placed into the opcodes. 63 64 // We must define the 64 bit int registers in two 32 bit halves, the 65 // real lower register and a virtual upper half register. upper halves 66 // are used by the register allocator but are not actually supplied as 67 // operands to memory ops. 68 // 69 // follow the C1 compiler in making registers 70 // 71 // x7, x9-x17, x27-x31 volatile (caller save) 72 // x0-x4, x8, x23 system (no save, no allocate) 73 // x5-x6 non-allocatable (so we can use them as temporary regs) 74 75 // 76 // as regards Java usage. we don't use any callee save registers 77 // because this makes it difficult to de-optimise a frame (see comment 78 // in x86 implementation of Deoptimization::unwind_callee_save_values) 79 // 80 81 // General Registers 82 83 reg_def R0 ( NS, NS, Op_RegI, 0, x0->as_VMReg() ); // zr 84 reg_def R0_H ( NS, NS, Op_RegI, 0, x0->as_VMReg()->next() ); 85 reg_def R1 ( NS, SOC, Op_RegI, 1, x1->as_VMReg() ); // ra 86 reg_def R1_H ( NS, SOC, Op_RegI, 1, x1->as_VMReg()->next() ); 87 reg_def R2 ( NS, NS, Op_RegI, 2, x2->as_VMReg() ); // sp 88 reg_def R2_H ( NS, NS, Op_RegI, 2, x2->as_VMReg()->next() ); 89 reg_def R3 ( NS, NS, Op_RegI, 3, x3->as_VMReg() ); // gp 90 reg_def R3_H ( NS, NS, Op_RegI, 3, x3->as_VMReg()->next() ); 91 reg_def R4 ( NS, NS, Op_RegI, 4, x4->as_VMReg() ); // tp 92 reg_def R4_H ( NS, NS, Op_RegI, 4, x4->as_VMReg()->next() ); 93 reg_def R7 ( SOC, SOC, Op_RegI, 7, x7->as_VMReg() ); 94 reg_def R7_H ( SOC, SOC, Op_RegI, 7, x7->as_VMReg()->next() ); 95 reg_def R8 ( NS, SOE, Op_RegI, 8, x8->as_VMReg() ); // fp 96 reg_def R8_H ( NS, SOE, Op_RegI, 8, x8->as_VMReg()->next() ); 97 reg_def R9 ( SOC, SOE, Op_RegI, 9, x9->as_VMReg() ); 98 reg_def R9_H ( SOC, SOE, Op_RegI, 9, x9->as_VMReg()->next() ); 99 reg_def R10 ( SOC, SOC, Op_RegI, 10, x10->as_VMReg() ); 100 reg_def R10_H ( SOC, SOC, Op_RegI, 10, x10->as_VMReg()->next()); 101 reg_def R11 ( SOC, SOC, Op_RegI, 11, x11->as_VMReg() ); 102 reg_def R11_H ( SOC, SOC, Op_RegI, 11, x11->as_VMReg()->next()); 103 reg_def R12 ( SOC, SOC, Op_RegI, 12, x12->as_VMReg() ); 104 reg_def R12_H ( SOC, SOC, Op_RegI, 12, x12->as_VMReg()->next()); 105 reg_def R13 ( SOC, SOC, Op_RegI, 13, x13->as_VMReg() ); 106 reg_def R13_H ( SOC, SOC, Op_RegI, 13, x13->as_VMReg()->next()); 107 reg_def R14 ( SOC, SOC, Op_RegI, 14, x14->as_VMReg() ); 108 reg_def R14_H ( SOC, SOC, Op_RegI, 14, x14->as_VMReg()->next()); 109 reg_def R15 ( SOC, SOC, Op_RegI, 15, x15->as_VMReg() ); 110 reg_def R15_H ( SOC, SOC, Op_RegI, 15, x15->as_VMReg()->next()); 111 reg_def R16 ( SOC, SOC, Op_RegI, 16, x16->as_VMReg() ); 112 reg_def R16_H ( SOC, SOC, Op_RegI, 16, x16->as_VMReg()->next()); 113 reg_def R17 ( SOC, SOC, Op_RegI, 17, x17->as_VMReg() ); 114 reg_def R17_H ( SOC, SOC, Op_RegI, 17, x17->as_VMReg()->next()); 115 reg_def R18 ( SOC, SOE, Op_RegI, 18, x18->as_VMReg() ); 116 reg_def R18_H ( SOC, SOE, Op_RegI, 18, x18->as_VMReg()->next()); 117 reg_def R19 ( SOC, SOE, Op_RegI, 19, x19->as_VMReg() ); 118 reg_def R19_H ( SOC, SOE, Op_RegI, 19, x19->as_VMReg()->next()); 119 reg_def R20 ( SOC, SOE, Op_RegI, 20, x20->as_VMReg() ); // caller esp 120 reg_def R20_H ( SOC, SOE, Op_RegI, 20, x20->as_VMReg()->next()); 121 reg_def R21 ( SOC, SOE, Op_RegI, 21, x21->as_VMReg() ); 122 reg_def R21_H ( SOC, SOE, Op_RegI, 21, x21->as_VMReg()->next()); 123 reg_def R22 ( SOC, SOE, Op_RegI, 22, x22->as_VMReg() ); 124 reg_def R22_H ( SOC, SOE, Op_RegI, 22, x22->as_VMReg()->next()); 125 reg_def R23 ( NS, SOE, Op_RegI, 23, x23->as_VMReg() ); // java thread 126 reg_def R23_H ( NS, SOE, Op_RegI, 23, x23->as_VMReg()->next()); 127 reg_def R24 ( SOC, SOE, Op_RegI, 24, x24->as_VMReg() ); 128 reg_def R24_H ( SOC, SOE, Op_RegI, 24, x24->as_VMReg()->next()); 129 reg_def R25 ( SOC, SOE, Op_RegI, 25, x25->as_VMReg() ); 130 reg_def R25_H ( SOC, SOE, Op_RegI, 25, x25->as_VMReg()->next()); 131 reg_def R26 ( SOC, SOE, Op_RegI, 26, x26->as_VMReg() ); 132 reg_def R26_H ( SOC, SOE, Op_RegI, 26, x26->as_VMReg()->next()); 133 reg_def R27 ( SOC, SOE, Op_RegI, 27, x27->as_VMReg() ); // heapbase 134 reg_def R27_H ( SOC, SOE, Op_RegI, 27, x27->as_VMReg()->next()); 135 reg_def R28 ( SOC, SOC, Op_RegI, 28, x28->as_VMReg() ); 136 reg_def R28_H ( SOC, SOC, Op_RegI, 28, x28->as_VMReg()->next()); 137 reg_def R29 ( SOC, SOC, Op_RegI, 29, x29->as_VMReg() ); 138 reg_def R29_H ( SOC, SOC, Op_RegI, 29, x29->as_VMReg()->next()); 139 reg_def R30 ( SOC, SOC, Op_RegI, 30, x30->as_VMReg() ); 140 reg_def R30_H ( SOC, SOC, Op_RegI, 30, x30->as_VMReg()->next()); 141 reg_def R31 ( SOC, SOC, Op_RegI, 31, x31->as_VMReg() ); 142 reg_def R31_H ( SOC, SOC, Op_RegI, 31, x31->as_VMReg()->next()); 143 144 // ---------------------------- 145 // Float/Double Registers 146 // ---------------------------- 147 148 // Double Registers 149 150 // The rules of ADL require that double registers be defined in pairs. 151 // Each pair must be two 32-bit values, but not necessarily a pair of 152 // single float registers. In each pair, ADLC-assigned register numbers 153 // must be adjacent, with the lower number even. Finally, when the 154 // CPU stores such a register pair to memory, the word associated with 155 // the lower ADLC-assigned number must be stored to the lower address. 156 157 // RISCV has 32 floating-point registers. Each can store a single 158 // or double precision floating-point value. 159 160 // for Java use float registers f0-f31 are always save on call whereas 161 // the platform ABI treats f8-f9 and f18-f27 as callee save). Other 162 // float registers are SOC as per the platform spec 163 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, f0->as_VMReg() ); 165 reg_def F0_H ( SOC, SOC, Op_RegF, 0, f0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, f1->as_VMReg() ); 167 reg_def F1_H ( SOC, SOC, Op_RegF, 1, f1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, f2->as_VMReg() ); 169 reg_def F2_H ( SOC, SOC, Op_RegF, 2, f2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, f3->as_VMReg() ); 171 reg_def F3_H ( SOC, SOC, Op_RegF, 3, f3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, f4->as_VMReg() ); 173 reg_def F4_H ( SOC, SOC, Op_RegF, 4, f4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, f5->as_VMReg() ); 175 reg_def F5_H ( SOC, SOC, Op_RegF, 5, f5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, f6->as_VMReg() ); 177 reg_def F6_H ( SOC, SOC, Op_RegF, 6, f6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, f7->as_VMReg() ); 179 reg_def F7_H ( SOC, SOC, Op_RegF, 7, f7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOE, Op_RegF, 8, f8->as_VMReg() ); 181 reg_def F8_H ( SOC, SOE, Op_RegF, 8, f8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOE, Op_RegF, 9, f9->as_VMReg() ); 183 reg_def F9_H ( SOC, SOE, Op_RegF, 9, f9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, f10->as_VMReg() ); 185 reg_def F10_H ( SOC, SOC, Op_RegF, 10, f10->as_VMReg()->next() ); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, f11->as_VMReg() ); 187 reg_def F11_H ( SOC, SOC, Op_RegF, 11, f11->as_VMReg()->next() ); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, f12->as_VMReg() ); 189 reg_def F12_H ( SOC, SOC, Op_RegF, 12, f12->as_VMReg()->next() ); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, f13->as_VMReg() ); 191 reg_def F13_H ( SOC, SOC, Op_RegF, 13, f13->as_VMReg()->next() ); 192 reg_def F14 ( SOC, SOC, Op_RegF, 14, f14->as_VMReg() ); 193 reg_def F14_H ( SOC, SOC, Op_RegF, 14, f14->as_VMReg()->next() ); 194 reg_def F15 ( SOC, SOC, Op_RegF, 15, f15->as_VMReg() ); 195 reg_def F15_H ( SOC, SOC, Op_RegF, 15, f15->as_VMReg()->next() ); 196 reg_def F16 ( SOC, SOC, Op_RegF, 16, f16->as_VMReg() ); 197 reg_def F16_H ( SOC, SOC, Op_RegF, 16, f16->as_VMReg()->next() ); 198 reg_def F17 ( SOC, SOC, Op_RegF, 17, f17->as_VMReg() ); 199 reg_def F17_H ( SOC, SOC, Op_RegF, 17, f17->as_VMReg()->next() ); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, f18->as_VMReg() ); 201 reg_def F18_H ( SOC, SOE, Op_RegF, 18, f18->as_VMReg()->next() ); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, f19->as_VMReg() ); 203 reg_def F19_H ( SOC, SOE, Op_RegF, 19, f19->as_VMReg()->next() ); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, f20->as_VMReg() ); 205 reg_def F20_H ( SOC, SOE, Op_RegF, 20, f20->as_VMReg()->next() ); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, f21->as_VMReg() ); 207 reg_def F21_H ( SOC, SOE, Op_RegF, 21, f21->as_VMReg()->next() ); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, f22->as_VMReg() ); 209 reg_def F22_H ( SOC, SOE, Op_RegF, 22, f22->as_VMReg()->next() ); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, f23->as_VMReg() ); 211 reg_def F23_H ( SOC, SOE, Op_RegF, 23, f23->as_VMReg()->next() ); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, f24->as_VMReg() ); 213 reg_def F24_H ( SOC, SOE, Op_RegF, 24, f24->as_VMReg()->next() ); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, f25->as_VMReg() ); 215 reg_def F25_H ( SOC, SOE, Op_RegF, 25, f25->as_VMReg()->next() ); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, f26->as_VMReg() ); 217 reg_def F26_H ( SOC, SOE, Op_RegF, 26, f26->as_VMReg()->next() ); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, f27->as_VMReg() ); 219 reg_def F27_H ( SOC, SOE, Op_RegF, 27, f27->as_VMReg()->next() ); 220 reg_def F28 ( SOC, SOC, Op_RegF, 28, f28->as_VMReg() ); 221 reg_def F28_H ( SOC, SOC, Op_RegF, 28, f28->as_VMReg()->next() ); 222 reg_def F29 ( SOC, SOC, Op_RegF, 29, f29->as_VMReg() ); 223 reg_def F29_H ( SOC, SOC, Op_RegF, 29, f29->as_VMReg()->next() ); 224 reg_def F30 ( SOC, SOC, Op_RegF, 30, f30->as_VMReg() ); 225 reg_def F30_H ( SOC, SOC, Op_RegF, 30, f30->as_VMReg()->next() ); 226 reg_def F31 ( SOC, SOC, Op_RegF, 31, f31->as_VMReg() ); 227 reg_def F31_H ( SOC, SOC, Op_RegF, 31, f31->as_VMReg()->next() ); 228 229 // ---------------------------- 230 // Vector Registers 231 // ---------------------------- 232 233 // For RVV vector registers, we simply extend vector register size to 4 234 // 'logical' slots. This is nominally 128 bits but it actually covers 235 // all possible 'physical' RVV vector register lengths from 128 ~ 1024 236 // bits. The 'physical' RVV vector register length is detected during 237 // startup, so the register allocator is able to identify the correct 238 // number of bytes needed for an RVV spill/unspill. 239 240 reg_def V0 ( SOC, SOC, Op_VecA, 0, v0->as_VMReg() ); 241 reg_def V0_H ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next() ); 242 reg_def V0_J ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(2) ); 243 reg_def V0_K ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(3) ); 244 245 reg_def V1 ( SOC, SOC, Op_VecA, 1, v1->as_VMReg() ); 246 reg_def V1_H ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next() ); 247 reg_def V1_J ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(2) ); 248 reg_def V1_K ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(3) ); 249 250 reg_def V2 ( SOC, SOC, Op_VecA, 2, v2->as_VMReg() ); 251 reg_def V2_H ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next() ); 252 reg_def V2_J ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(2) ); 253 reg_def V2_K ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(3) ); 254 255 reg_def V3 ( SOC, SOC, Op_VecA, 3, v3->as_VMReg() ); 256 reg_def V3_H ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next() ); 257 reg_def V3_J ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(2) ); 258 reg_def V3_K ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(3) ); 259 260 reg_def V4 ( SOC, SOC, Op_VecA, 4, v4->as_VMReg() ); 261 reg_def V4_H ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next() ); 262 reg_def V4_J ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(2) ); 263 reg_def V4_K ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(3) ); 264 265 reg_def V5 ( SOC, SOC, Op_VecA, 5, v5->as_VMReg() ); 266 reg_def V5_H ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next() ); 267 reg_def V5_J ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(2) ); 268 reg_def V5_K ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(3) ); 269 270 reg_def V6 ( SOC, SOC, Op_VecA, 6, v6->as_VMReg() ); 271 reg_def V6_H ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next() ); 272 reg_def V6_J ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(2) ); 273 reg_def V6_K ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(3) ); 274 275 reg_def V7 ( SOC, SOC, Op_VecA, 7, v7->as_VMReg() ); 276 reg_def V7_H ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next() ); 277 reg_def V7_J ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(2) ); 278 reg_def V7_K ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(3) ); 279 280 reg_def V8 ( SOC, SOC, Op_VecA, 8, v8->as_VMReg() ); 281 reg_def V8_H ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next() ); 282 reg_def V8_J ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(2) ); 283 reg_def V8_K ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(3) ); 284 285 reg_def V9 ( SOC, SOC, Op_VecA, 9, v9->as_VMReg() ); 286 reg_def V9_H ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next() ); 287 reg_def V9_J ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(2) ); 288 reg_def V9_K ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(3) ); 289 290 reg_def V10 ( SOC, SOC, Op_VecA, 10, v10->as_VMReg() ); 291 reg_def V10_H ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next() ); 292 reg_def V10_J ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(2) ); 293 reg_def V10_K ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(3) ); 294 295 reg_def V11 ( SOC, SOC, Op_VecA, 11, v11->as_VMReg() ); 296 reg_def V11_H ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next() ); 297 reg_def V11_J ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(2) ); 298 reg_def V11_K ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(3) ); 299 300 reg_def V12 ( SOC, SOC, Op_VecA, 12, v12->as_VMReg() ); 301 reg_def V12_H ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next() ); 302 reg_def V12_J ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(2) ); 303 reg_def V12_K ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(3) ); 304 305 reg_def V13 ( SOC, SOC, Op_VecA, 13, v13->as_VMReg() ); 306 reg_def V13_H ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next() ); 307 reg_def V13_J ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(2) ); 308 reg_def V13_K ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(3) ); 309 310 reg_def V14 ( SOC, SOC, Op_VecA, 14, v14->as_VMReg() ); 311 reg_def V14_H ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next() ); 312 reg_def V14_J ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(2) ); 313 reg_def V14_K ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(3) ); 314 315 reg_def V15 ( SOC, SOC, Op_VecA, 15, v15->as_VMReg() ); 316 reg_def V15_H ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next() ); 317 reg_def V15_J ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(2) ); 318 reg_def V15_K ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(3) ); 319 320 reg_def V16 ( SOC, SOC, Op_VecA, 16, v16->as_VMReg() ); 321 reg_def V16_H ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next() ); 322 reg_def V16_J ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(2) ); 323 reg_def V16_K ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(3) ); 324 325 reg_def V17 ( SOC, SOC, Op_VecA, 17, v17->as_VMReg() ); 326 reg_def V17_H ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next() ); 327 reg_def V17_J ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(2) ); 328 reg_def V17_K ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(3) ); 329 330 reg_def V18 ( SOC, SOC, Op_VecA, 18, v18->as_VMReg() ); 331 reg_def V18_H ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next() ); 332 reg_def V18_J ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(2) ); 333 reg_def V18_K ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(3) ); 334 335 reg_def V19 ( SOC, SOC, Op_VecA, 19, v19->as_VMReg() ); 336 reg_def V19_H ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next() ); 337 reg_def V19_J ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(2) ); 338 reg_def V19_K ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(3) ); 339 340 reg_def V20 ( SOC, SOC, Op_VecA, 20, v20->as_VMReg() ); 341 reg_def V20_H ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next() ); 342 reg_def V20_J ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(2) ); 343 reg_def V20_K ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(3) ); 344 345 reg_def V21 ( SOC, SOC, Op_VecA, 21, v21->as_VMReg() ); 346 reg_def V21_H ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next() ); 347 reg_def V21_J ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(2) ); 348 reg_def V21_K ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(3) ); 349 350 reg_def V22 ( SOC, SOC, Op_VecA, 22, v22->as_VMReg() ); 351 reg_def V22_H ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next() ); 352 reg_def V22_J ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(2) ); 353 reg_def V22_K ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(3) ); 354 355 reg_def V23 ( SOC, SOC, Op_VecA, 23, v23->as_VMReg() ); 356 reg_def V23_H ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next() ); 357 reg_def V23_J ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(2) ); 358 reg_def V23_K ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(3) ); 359 360 reg_def V24 ( SOC, SOC, Op_VecA, 24, v24->as_VMReg() ); 361 reg_def V24_H ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next() ); 362 reg_def V24_J ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(2) ); 363 reg_def V24_K ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(3) ); 364 365 reg_def V25 ( SOC, SOC, Op_VecA, 25, v25->as_VMReg() ); 366 reg_def V25_H ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next() ); 367 reg_def V25_J ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(2) ); 368 reg_def V25_K ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(3) ); 369 370 reg_def V26 ( SOC, SOC, Op_VecA, 26, v26->as_VMReg() ); 371 reg_def V26_H ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next() ); 372 reg_def V26_J ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(2) ); 373 reg_def V26_K ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(3) ); 374 375 reg_def V27 ( SOC, SOC, Op_VecA, 27, v27->as_VMReg() ); 376 reg_def V27_H ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next() ); 377 reg_def V27_J ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(2) ); 378 reg_def V27_K ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(3) ); 379 380 reg_def V28 ( SOC, SOC, Op_VecA, 28, v28->as_VMReg() ); 381 reg_def V28_H ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next() ); 382 reg_def V28_J ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(2) ); 383 reg_def V28_K ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(3) ); 384 385 reg_def V29 ( SOC, SOC, Op_VecA, 29, v29->as_VMReg() ); 386 reg_def V29_H ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next() ); 387 reg_def V29_J ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(2) ); 388 reg_def V29_K ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(3) ); 389 390 reg_def V30 ( SOC, SOC, Op_VecA, 30, v30->as_VMReg() ); 391 reg_def V30_H ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next() ); 392 reg_def V30_J ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(2) ); 393 reg_def V30_K ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(3) ); 394 395 reg_def V31 ( SOC, SOC, Op_VecA, 31, v31->as_VMReg() ); 396 reg_def V31_H ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next() ); 397 reg_def V31_J ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(2) ); 398 reg_def V31_K ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(3) ); 399 400 // ---------------------------- 401 // Special Registers 402 // ---------------------------- 403 404 // On riscv, the physical flag register is missing, so we use t1 instead, 405 // to bridge the RegFlag semantics in share/opto 406 407 reg_def RFLAGS (SOC, SOC, Op_RegFlags, 6, x6->as_VMReg() ); 408 409 // Specify priority of register selection within phases of register 410 // allocation. Highest priority is first. A useful heuristic is to 411 // give registers a low priority when they are required by machine 412 // instructions, like EAX and EDX on I486, and choose no-save registers 413 // before save-on-call, & save-on-call before save-on-entry. Registers 414 // which participate in fixed calling sequences should come last. 415 // Registers which are used as pairs must fall on an even boundary. 416 417 alloc_class chunk0( 418 // volatiles 419 R7, R7_H, 420 R28, R28_H, 421 R29, R29_H, 422 R30, R30_H, 423 R31, R31_H, 424 425 // arg registers 426 R10, R10_H, 427 R11, R11_H, 428 R12, R12_H, 429 R13, R13_H, 430 R14, R14_H, 431 R15, R15_H, 432 R16, R16_H, 433 R17, R17_H, 434 435 // non-volatiles 436 R9, R9_H, 437 R18, R18_H, 438 R19, R19_H, 439 R20, R20_H, 440 R21, R21_H, 441 R22, R22_H, 442 R24, R24_H, 443 R25, R25_H, 444 R26, R26_H, 445 446 // non-allocatable registers 447 R23, R23_H, // java thread 448 R27, R27_H, // heapbase 449 R4, R4_H, // thread 450 R8, R8_H, // fp 451 R0, R0_H, // zero 452 R1, R1_H, // ra 453 R2, R2_H, // sp 454 R3, R3_H, // gp 455 ); 456 457 alloc_class chunk1( 458 459 // no save 460 F0, F0_H, 461 F1, F1_H, 462 F2, F2_H, 463 F3, F3_H, 464 F4, F4_H, 465 F5, F5_H, 466 F6, F6_H, 467 F7, F7_H, 468 F28, F28_H, 469 F29, F29_H, 470 F30, F30_H, 471 F31, F31_H, 472 473 // arg registers 474 F10, F10_H, 475 F11, F11_H, 476 F12, F12_H, 477 F13, F13_H, 478 F14, F14_H, 479 F15, F15_H, 480 F16, F16_H, 481 F17, F17_H, 482 483 // non-volatiles 484 F8, F8_H, 485 F9, F9_H, 486 F18, F18_H, 487 F19, F19_H, 488 F20, F20_H, 489 F21, F21_H, 490 F22, F22_H, 491 F23, F23_H, 492 F24, F24_H, 493 F25, F25_H, 494 F26, F26_H, 495 F27, F27_H, 496 ); 497 498 alloc_class chunk2( 499 V0, V0_H, V0_J, V0_K, 500 V1, V1_H, V1_J, V1_K, 501 V2, V2_H, V2_J, V2_K, 502 V3, V3_H, V3_J, V3_K, 503 V4, V4_H, V4_J, V4_K, 504 V5, V5_H, V5_J, V5_K, 505 V6, V6_H, V6_J, V6_K, 506 V7, V7_H, V7_J, V7_K, 507 V8, V8_H, V8_J, V8_K, 508 V9, V9_H, V9_J, V9_K, 509 V10, V10_H, V10_J, V10_K, 510 V11, V11_H, V11_J, V11_K, 511 V12, V12_H, V12_J, V12_K, 512 V13, V13_H, V13_J, V13_K, 513 V14, V14_H, V14_J, V14_K, 514 V15, V15_H, V15_J, V15_K, 515 V16, V16_H, V16_J, V16_K, 516 V17, V17_H, V17_J, V17_K, 517 V18, V18_H, V18_J, V18_K, 518 V19, V19_H, V19_J, V19_K, 519 V20, V20_H, V20_J, V20_K, 520 V21, V21_H, V21_J, V21_K, 521 V22, V22_H, V22_J, V22_K, 522 V23, V23_H, V23_J, V23_K, 523 V24, V24_H, V24_J, V24_K, 524 V25, V25_H, V25_J, V25_K, 525 V26, V26_H, V26_J, V26_K, 526 V27, V27_H, V27_J, V27_K, 527 V28, V28_H, V28_J, V28_K, 528 V29, V29_H, V29_J, V29_K, 529 V30, V30_H, V30_J, V30_K, 530 V31, V31_H, V31_J, V31_K, 531 ); 532 533 alloc_class chunk3(RFLAGS); 534 535 //----------Architecture Description Register Classes-------------------------- 536 // Several register classes are automatically defined based upon information in 537 // this architecture description. 538 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 539 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 540 // 541 542 // Class for all 32 bit general purpose registers 543 reg_class all_reg32( 544 R0, 545 R1, 546 R2, 547 R3, 548 R4, 549 R7, 550 R8, 551 R9, 552 R10, 553 R11, 554 R12, 555 R13, 556 R14, 557 R15, 558 R16, 559 R17, 560 R18, 561 R19, 562 R20, 563 R21, 564 R22, 565 R23, 566 R24, 567 R25, 568 R26, 569 R27, 570 R28, 571 R29, 572 R30, 573 R31 574 ); 575 576 // Class for any 32 bit integer registers (excluding zr) 577 reg_class any_reg32 %{ 578 return _ANY_REG32_mask; 579 %} 580 581 // Singleton class for R10 int register 582 reg_class int_r10_reg(R10); 583 584 // Singleton class for R12 int register 585 reg_class int_r12_reg(R12); 586 587 // Singleton class for R13 int register 588 reg_class int_r13_reg(R13); 589 590 // Singleton class for R14 int register 591 reg_class int_r14_reg(R14); 592 593 // Class for all long integer registers 594 reg_class all_reg( 595 R0, R0_H, 596 R1, R1_H, 597 R2, R2_H, 598 R3, R3_H, 599 R4, R4_H, 600 R7, R7_H, 601 R8, R8_H, 602 R9, R9_H, 603 R10, R10_H, 604 R11, R11_H, 605 R12, R12_H, 606 R13, R13_H, 607 R14, R14_H, 608 R15, R15_H, 609 R16, R16_H, 610 R17, R17_H, 611 R18, R18_H, 612 R19, R19_H, 613 R20, R20_H, 614 R21, R21_H, 615 R22, R22_H, 616 R23, R23_H, 617 R24, R24_H, 618 R25, R25_H, 619 R26, R26_H, 620 R27, R27_H, 621 R28, R28_H, 622 R29, R29_H, 623 R30, R30_H, 624 R31, R31_H 625 ); 626 627 // Class for all long integer registers (excluding zr) 628 reg_class any_reg %{ 629 return _ANY_REG_mask; 630 %} 631 632 // Class for non-allocatable 32 bit registers 633 reg_class non_allocatable_reg32( 634 R0, // zr 635 R1, // ra 636 R2, // sp 637 R3, // gp 638 R4, // tp 639 R23 // java thread 640 ); 641 642 // Class for non-allocatable 64 bit registers 643 reg_class non_allocatable_reg( 644 R0, R0_H, // zr 645 R1, R1_H, // ra 646 R2, R2_H, // sp 647 R3, R3_H, // gp 648 R4, R4_H, // tp 649 R23, R23_H // java thread 650 ); 651 652 // Class for all non-special integer registers 653 reg_class no_special_reg32 %{ 654 return _NO_SPECIAL_REG32_mask; 655 %} 656 657 // Class for all non-special long integer registers 658 reg_class no_special_reg %{ 659 return _NO_SPECIAL_REG_mask; 660 %} 661 662 reg_class ptr_reg %{ 663 return _PTR_REG_mask; 664 %} 665 666 // Class for all non_special pointer registers 667 reg_class no_special_ptr_reg %{ 668 return _NO_SPECIAL_PTR_REG_mask; 669 %} 670 671 // Class for all non_special pointer registers (excluding fp) 672 reg_class no_special_no_fp_ptr_reg %{ 673 return _NO_SPECIAL_NO_FP_PTR_REG_mask; 674 %} 675 676 // Class for 64 bit register r10 677 reg_class r10_reg( 678 R10, R10_H 679 ); 680 681 // Class for 64 bit register r11 682 reg_class r11_reg( 683 R11, R11_H 684 ); 685 686 // Class for 64 bit register r12 687 reg_class r12_reg( 688 R12, R12_H 689 ); 690 691 // Class for 64 bit register r13 692 reg_class r13_reg( 693 R13, R13_H 694 ); 695 696 // Class for 64 bit register r14 697 reg_class r14_reg( 698 R14, R14_H 699 ); 700 701 // Class for 64 bit register r15 702 reg_class r15_reg( 703 R15, R15_H 704 ); 705 706 // Class for 64 bit register r16 707 reg_class r16_reg( 708 R16, R16_H 709 ); 710 711 // Class for method register 712 reg_class method_reg( 713 R31, R31_H 714 ); 715 716 // Class for java thread register 717 reg_class java_thread_reg( 718 R23, R23_H 719 ); 720 721 reg_class r28_reg( 722 R28, R28_H 723 ); 724 725 reg_class r29_reg( 726 R29, R29_H 727 ); 728 729 reg_class r30_reg( 730 R30, R30_H 731 ); 732 733 reg_class r31_reg( 734 R31, R31_H 735 ); 736 737 // Class for zero registesr 738 reg_class zr_reg( 739 R0, R0_H 740 ); 741 742 // Class for thread register 743 reg_class thread_reg( 744 R4, R4_H 745 ); 746 747 // Class for frame pointer register 748 reg_class fp_reg( 749 R8, R8_H 750 ); 751 752 // Class for link register 753 reg_class ra_reg( 754 R1, R1_H 755 ); 756 757 // Class for long sp register 758 reg_class sp_reg( 759 R2, R2_H 760 ); 761 762 // Class for all float registers 763 reg_class float_reg( 764 F0, 765 F1, 766 F2, 767 F3, 768 F4, 769 F5, 770 F6, 771 F7, 772 F8, 773 F9, 774 F10, 775 F11, 776 F12, 777 F13, 778 F14, 779 F15, 780 F16, 781 F17, 782 F18, 783 F19, 784 F20, 785 F21, 786 F22, 787 F23, 788 F24, 789 F25, 790 F26, 791 F27, 792 F28, 793 F29, 794 F30, 795 F31 796 ); 797 798 // Double precision float registers have virtual `high halves' that 799 // are needed by the allocator. 800 // Class for all double registers 801 reg_class double_reg( 802 F0, F0_H, 803 F1, F1_H, 804 F2, F2_H, 805 F3, F3_H, 806 F4, F4_H, 807 F5, F5_H, 808 F6, F6_H, 809 F7, F7_H, 810 F8, F8_H, 811 F9, F9_H, 812 F10, F10_H, 813 F11, F11_H, 814 F12, F12_H, 815 F13, F13_H, 816 F14, F14_H, 817 F15, F15_H, 818 F16, F16_H, 819 F17, F17_H, 820 F18, F18_H, 821 F19, F19_H, 822 F20, F20_H, 823 F21, F21_H, 824 F22, F22_H, 825 F23, F23_H, 826 F24, F24_H, 827 F25, F25_H, 828 F26, F26_H, 829 F27, F27_H, 830 F28, F28_H, 831 F29, F29_H, 832 F30, F30_H, 833 F31, F31_H 834 ); 835 836 // Class for RVV vector registers 837 // Note: v0, v30 and v31 are used as mask registers. 838 reg_class vectora_reg( 839 V1, V1_H, V1_J, V1_K, 840 V2, V2_H, V2_J, V2_K, 841 V3, V3_H, V3_J, V3_K, 842 V4, V4_H, V4_J, V4_K, 843 V5, V5_H, V5_J, V5_K, 844 V6, V6_H, V6_J, V6_K, 845 V7, V7_H, V7_J, V7_K, 846 V8, V8_H, V8_J, V8_K, 847 V9, V9_H, V9_J, V9_K, 848 V10, V10_H, V10_J, V10_K, 849 V11, V11_H, V11_J, V11_K, 850 V12, V12_H, V12_J, V12_K, 851 V13, V13_H, V13_J, V13_K, 852 V14, V14_H, V14_J, V14_K, 853 V15, V15_H, V15_J, V15_K, 854 V16, V16_H, V16_J, V16_K, 855 V17, V17_H, V17_J, V17_K, 856 V18, V18_H, V18_J, V18_K, 857 V19, V19_H, V19_J, V19_K, 858 V20, V20_H, V20_J, V20_K, 859 V21, V21_H, V21_J, V21_K, 860 V22, V22_H, V22_J, V22_K, 861 V23, V23_H, V23_J, V23_K, 862 V24, V24_H, V24_J, V24_K, 863 V25, V25_H, V25_J, V25_K, 864 V26, V26_H, V26_J, V26_K, 865 V27, V27_H, V27_J, V27_K, 866 V28, V28_H, V28_J, V28_K, 867 V29, V29_H, V29_J, V29_K 868 ); 869 870 // Class for 64 bit register f0 871 reg_class f0_reg( 872 F0, F0_H 873 ); 874 875 // Class for 64 bit register f1 876 reg_class f1_reg( 877 F1, F1_H 878 ); 879 880 // Class for 64 bit register f2 881 reg_class f2_reg( 882 F2, F2_H 883 ); 884 885 // Class for 64 bit register f3 886 reg_class f3_reg( 887 F3, F3_H 888 ); 889 890 // class for vector register v1 891 reg_class v1_reg( 892 V1, V1_H, V1_J, V1_K 893 ); 894 895 // class for vector register v2 896 reg_class v2_reg( 897 V2, V2_H, V2_J, V2_K 898 ); 899 900 // class for vector register v3 901 reg_class v3_reg( 902 V3, V3_H, V3_J, V3_K 903 ); 904 905 // class for vector register v4 906 reg_class v4_reg( 907 V4, V4_H, V4_J, V4_K 908 ); 909 910 // class for vector register v5 911 reg_class v5_reg( 912 V5, V5_H, V5_J, V5_K 913 ); 914 915 // class for vector register v6 916 reg_class v6_reg( 917 V6, V6_H, V6_J, V6_K 918 ); 919 920 // class for vector register v7 921 reg_class v7_reg( 922 V7, V7_H, V7_J, V7_K 923 ); 924 925 // class for vector register v8 926 reg_class v8_reg( 927 V8, V8_H, V8_J, V8_K 928 ); 929 930 // class for vector register v9 931 reg_class v9_reg( 932 V9, V9_H, V9_J, V9_K 933 ); 934 935 // class for vector register v10 936 reg_class v10_reg( 937 V10, V10_H, V10_J, V10_K 938 ); 939 940 // class for vector register v11 941 reg_class v11_reg( 942 V11, V11_H, V11_J, V11_K 943 ); 944 945 // class for vector register v12 946 reg_class v12_reg( 947 V12, V12_H, V12_J, V12_K 948 ); 949 950 // class for vector register v13 951 reg_class v13_reg( 952 V13, V13_H, V13_J, V13_K 953 ); 954 955 // class for vector register v14 956 reg_class v14_reg( 957 V14, V14_H, V14_J, V14_K 958 ); 959 960 // class for vector register v15 961 reg_class v15_reg( 962 V15, V15_H, V15_J, V15_K 963 ); 964 965 // class for condition codes 966 reg_class reg_flags(RFLAGS); 967 968 // Class for RVV v0 mask register 969 // https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#53-vector-masking 970 // The mask value used to control execution of a masked vector 971 // instruction is always supplied by vector register v0. 972 reg_class vmask_reg_v0 ( 973 V0 974 ); 975 976 // Class for RVV mask registers 977 // We need two more vmask registers to do the vector mask logical ops, 978 // so define v30, v31 as mask register too. 979 reg_class vmask_reg ( 980 V0, 981 V30, 982 V31 983 ); 984 %} 985 986 //----------DEFINITION BLOCK--------------------------------------------------- 987 // Define name --> value mappings to inform the ADLC of an integer valued name 988 // Current support includes integer values in the range [0, 0x7FFFFFFF] 989 // Format: 990 // int_def <name> ( <int_value>, <expression>); 991 // Generated Code in ad_<arch>.hpp 992 // #define <name> (<expression>) 993 // // value == <int_value> 994 // Generated code in ad_<arch>.cpp adlc_verification() 995 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 996 // 997 998 // we follow the ppc-aix port in using a simple cost model which ranks 999 // register operations as cheap, memory ops as more expensive and 1000 // branches as most expensive. the first two have a low as well as a 1001 // normal cost. huge cost appears to be a way of saying don't do 1002 // something 1003 1004 definitions %{ 1005 // The default cost (of a register move instruction). 1006 int_def DEFAULT_COST ( 100, 100); 1007 int_def ALU_COST ( 100, 1 * DEFAULT_COST); // unknown, const, arith, shift, slt, 1008 // multi, auipc, nop, logical, move 1009 int_def LOAD_COST ( 300, 3 * DEFAULT_COST); // load, fpload 1010 int_def STORE_COST ( 100, 1 * DEFAULT_COST); // store, fpstore 1011 int_def XFER_COST ( 300, 3 * DEFAULT_COST); // mfc, mtc, fcvt, fmove, fcmp 1012 int_def FMVX_COST ( 100, 1 * DEFAULT_COST); // shuffles with no conversion 1013 int_def BRANCH_COST ( 200, 2 * DEFAULT_COST); // branch, jmp, call 1014 int_def IMUL_COST ( 1000, 10 * DEFAULT_COST); // imul 1015 int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivsi 1016 int_def IDIVDI_COST ( 6600, 66 * DEFAULT_COST); // idivdi 1017 int_def FMUL_SINGLE_COST ( 500, 5 * DEFAULT_COST); // fmul, fmadd 1018 int_def FMUL_DOUBLE_COST ( 700, 7 * DEFAULT_COST); // fmul, fmadd 1019 int_def FDIV_COST ( 2000, 20 * DEFAULT_COST); // fdiv 1020 int_def FSQRT_COST ( 2500, 25 * DEFAULT_COST); // fsqrt 1021 int_def VOLATILE_REF_COST ( 1000, 10 * DEFAULT_COST); 1022 int_def CACHE_MISS_COST ( 2000, 20 * DEFAULT_COST); // typicall cache miss penalty 1023 %} 1024 1025 1026 1027 //----------SOURCE BLOCK------------------------------------------------------- 1028 // This is a block of C++ code which provides values, functions, and 1029 // definitions necessary in the rest of the architecture description 1030 1031 source_hpp %{ 1032 1033 #include "asm/macroAssembler.hpp" 1034 #include "gc/shared/barrierSetAssembler.hpp" 1035 #include "gc/shared/cardTable.hpp" 1036 #include "gc/shared/cardTableBarrierSet.hpp" 1037 #include "gc/shared/collectedHeap.hpp" 1038 #include "opto/addnode.hpp" 1039 #include "opto/convertnode.hpp" 1040 #include "runtime/objectMonitor.hpp" 1041 1042 extern RegMask _ANY_REG32_mask; 1043 extern RegMask _ANY_REG_mask; 1044 extern RegMask _PTR_REG_mask; 1045 extern RegMask _NO_SPECIAL_REG32_mask; 1046 extern RegMask _NO_SPECIAL_REG_mask; 1047 extern RegMask _NO_SPECIAL_PTR_REG_mask; 1048 extern RegMask _NO_SPECIAL_NO_FP_PTR_REG_mask; 1049 1050 class CallStubImpl { 1051 1052 //-------------------------------------------------------------- 1053 //---< Used for optimization in Compile::shorten_branches >--- 1054 //-------------------------------------------------------------- 1055 1056 public: 1057 // Size of call trampoline stub. 1058 static uint size_call_trampoline() { 1059 return 0; // no call trampolines on this platform 1060 } 1061 1062 // number of relocations needed by a call trampoline stub 1063 static uint reloc_call_trampoline() { 1064 return 0; // no call trampolines on this platform 1065 } 1066 }; 1067 1068 class HandlerImpl { 1069 1070 public: 1071 1072 static int emit_exception_handler(C2_MacroAssembler *masm); 1073 static int emit_deopt_handler(C2_MacroAssembler* masm); 1074 1075 static uint size_exception_handler() { 1076 return MacroAssembler::far_branch_size(); 1077 } 1078 1079 static uint size_deopt_handler() { 1080 // count auipc + far branch 1081 return NativeInstruction::instruction_size + MacroAssembler::far_branch_size(); 1082 } 1083 }; 1084 1085 class Node::PD { 1086 public: 1087 enum NodeFlags { 1088 _last_flag = Node::_last_flag 1089 }; 1090 }; 1091 1092 bool is_CAS(int opcode, bool maybe_volatile); 1093 1094 // predicate controlling translation of CompareAndSwapX 1095 bool needs_acquiring_load_reserved(const Node *load); 1096 1097 // predicate controlling addressing modes 1098 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1099 %} 1100 1101 source %{ 1102 1103 // Derived RegMask with conditionally allocatable registers 1104 1105 RegMask _ANY_REG32_mask; 1106 RegMask _ANY_REG_mask; 1107 RegMask _PTR_REG_mask; 1108 RegMask _NO_SPECIAL_REG32_mask; 1109 RegMask _NO_SPECIAL_REG_mask; 1110 RegMask _NO_SPECIAL_PTR_REG_mask; 1111 RegMask _NO_SPECIAL_NO_FP_PTR_REG_mask; 1112 1113 void reg_mask_init() { 1114 1115 _ANY_REG32_mask = _ALL_REG32_mask; 1116 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(x0->as_VMReg())); 1117 1118 _ANY_REG_mask = _ALL_REG_mask; 1119 _ANY_REG_mask.SUBTRACT(_ZR_REG_mask); 1120 1121 _PTR_REG_mask = _ALL_REG_mask; 1122 _PTR_REG_mask.SUBTRACT(_ZR_REG_mask); 1123 1124 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1125 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1126 1127 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1128 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1129 1130 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1131 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1132 1133 // x27 is not allocatable when compressed oops is on 1134 if (UseCompressedOops) { 1135 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(x27->as_VMReg())); 1136 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(x27->as_VMReg())); 1137 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(x27->as_VMReg())); 1138 } 1139 1140 // x8 is not allocatable when PreserveFramePointer is on 1141 if (PreserveFramePointer) { 1142 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(x8->as_VMReg())); 1143 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(x8->as_VMReg())); 1144 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(x8->as_VMReg())); 1145 } 1146 1147 _NO_SPECIAL_NO_FP_PTR_REG_mask = _NO_SPECIAL_PTR_REG_mask; 1148 _NO_SPECIAL_NO_FP_PTR_REG_mask.Remove(OptoReg::as_OptoReg(x8->as_VMReg())); 1149 } 1150 1151 void PhaseOutput::pd_perform_mach_node_analysis() { 1152 } 1153 1154 int MachNode::pd_alignment_required() const { 1155 return 1; 1156 } 1157 1158 int MachNode::compute_padding(int current_offset) const { 1159 return 0; 1160 } 1161 1162 // is_CAS(int opcode, bool maybe_volatile) 1163 // 1164 // return true if opcode is one of the possible CompareAndSwapX 1165 // values otherwise false. 1166 bool is_CAS(int opcode, bool maybe_volatile) 1167 { 1168 switch (opcode) { 1169 // We handle these 1170 case Op_CompareAndSwapI: 1171 case Op_CompareAndSwapL: 1172 case Op_CompareAndSwapP: 1173 case Op_CompareAndSwapN: 1174 case Op_ShenandoahCompareAndSwapP: 1175 case Op_ShenandoahCompareAndSwapN: 1176 case Op_CompareAndSwapB: 1177 case Op_CompareAndSwapS: 1178 case Op_GetAndSetI: 1179 case Op_GetAndSetL: 1180 case Op_GetAndSetP: 1181 case Op_GetAndSetN: 1182 case Op_GetAndAddI: 1183 case Op_GetAndAddL: 1184 return true; 1185 case Op_CompareAndExchangeI: 1186 case Op_CompareAndExchangeN: 1187 case Op_CompareAndExchangeB: 1188 case Op_CompareAndExchangeS: 1189 case Op_CompareAndExchangeL: 1190 case Op_CompareAndExchangeP: 1191 case Op_WeakCompareAndSwapB: 1192 case Op_WeakCompareAndSwapS: 1193 case Op_WeakCompareAndSwapI: 1194 case Op_WeakCompareAndSwapL: 1195 case Op_WeakCompareAndSwapP: 1196 case Op_WeakCompareAndSwapN: 1197 case Op_ShenandoahWeakCompareAndSwapP: 1198 case Op_ShenandoahWeakCompareAndSwapN: 1199 case Op_ShenandoahCompareAndExchangeP: 1200 case Op_ShenandoahCompareAndExchangeN: 1201 return maybe_volatile; 1202 default: 1203 return false; 1204 } 1205 } 1206 1207 // predicate controlling translation of CAS 1208 // 1209 // returns true if CAS needs to use an acquiring load otherwise false 1210 bool needs_acquiring_load_reserved(const Node *n) 1211 { 1212 assert(n != nullptr && is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1213 1214 LoadStoreNode* ldst = n->as_LoadStore(); 1215 if (n != nullptr && is_CAS(n->Opcode(), false)) { 1216 assert(ldst != nullptr && ldst->trailing_membar() != nullptr, "expected trailing membar"); 1217 } else { 1218 return ldst != nullptr && ldst->trailing_membar() != nullptr; 1219 } 1220 // so we can just return true here 1221 return true; 1222 } 1223 #define __ masm-> 1224 1225 // advance declarations for helper functions to convert register 1226 // indices to register objects 1227 1228 // the ad file has to provide implementations of certain methods 1229 // expected by the generic code 1230 // 1231 // REQUIRED FUNCTIONALITY 1232 1233 //============================================================================= 1234 1235 // !!!!! Special hack to get all types of calls to specify the byte offset 1236 // from the start of the call to the point where the return address 1237 // will point. 1238 1239 int MachCallStaticJavaNode::ret_addr_offset() 1240 { 1241 if (UseTrampolines) { 1242 return 1 * NativeInstruction::instruction_size; // jal 1243 } 1244 return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr 1245 } 1246 1247 int MachCallDynamicJavaNode::ret_addr_offset() 1248 { 1249 if (UseTrampolines) { 1250 return NativeMovConstReg::movptr2_instruction_size + NativeInstruction::instruction_size; // movptr2, jal 1251 } 1252 return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal 1253 } 1254 1255 int MachCallRuntimeNode::ret_addr_offset() { 1256 // For generated stubs the call will be: 1257 // auipc + ld + jalr 1258 // Using trampos: 1259 // jal(addr) 1260 // or with far branches 1261 // jal(trampoline_stub) 1262 // for real runtime callouts it will be 11 instructions 1263 // see riscv_enc_java_to_runtime 1264 // la(t1, retaddr) -> auipc + addi 1265 // la(t0, RuntimeAddress(addr)) -> lui + addi + slli + addi + slli + addi 1266 // addi(sp, sp, -2 * wordSize) -> addi 1267 // sd(t1, Address(sp, wordSize)) -> sd 1268 // jalr(t0) -> jalr 1269 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1270 if (cb != nullptr) { 1271 if (UseTrampolines) { 1272 return 1 * NativeInstruction::instruction_size; 1273 } 1274 return 3 * NativeInstruction::instruction_size; 1275 } else { 1276 return 11 * NativeInstruction::instruction_size; 1277 } 1278 } 1279 1280 // 1281 // Compute padding required for nodes which need alignment 1282 // 1283 1284 // With RVC a call instruction may get 2-byte aligned. 1285 // The address of the call instruction needs to be 4-byte aligned to 1286 // ensure that it does not span a cache line so that it can be patched. 1287 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 1288 { 1289 // to make sure the address of jal 4-byte aligned. 1290 return align_up(current_offset, alignment_required()) - current_offset; 1291 } 1292 1293 // With RVC a call instruction may get 2-byte aligned. 1294 // The address of the call instruction needs to be 4-byte aligned to 1295 // ensure that it does not span a cache line so that it can be patched. 1296 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 1297 { 1298 // skip the movptr2 in MacroAssembler::ic_call(): 1299 // lui, lui, slli, add, addi 1300 // Though movptr2() has already 4-byte aligned with or without RVC, 1301 // We need to prevent from further changes by explicitly calculating the size. 1302 current_offset += NativeMovConstReg::movptr2_instruction_size; 1303 // to make sure the address of jal 4-byte aligned. 1304 return align_up(current_offset, alignment_required()) - current_offset; 1305 } 1306 1307 //============================================================================= 1308 1309 #ifndef PRODUCT 1310 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1311 assert_cond(st != nullptr); 1312 st->print("BREAKPOINT"); 1313 } 1314 #endif 1315 1316 void MachBreakpointNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1317 __ ebreak(); 1318 } 1319 1320 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1321 return MachNode::size(ra_); 1322 } 1323 1324 //============================================================================= 1325 1326 #ifndef PRODUCT 1327 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1328 st->print("nop \t# %d bytes pad for loops and calls", _count); 1329 } 1330 #endif 1331 1332 void MachNopNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc*) const { 1333 Assembler::CompressibleRegion cr(masm); // nops shall be 2-byte under RVC for alignment purposes. 1334 for (int i = 0; i < _count; i++) { 1335 __ nop(); 1336 } 1337 } 1338 1339 uint MachNopNode::size(PhaseRegAlloc*) const { 1340 return _count * (UseRVC ? NativeInstruction::compressed_instruction_size : NativeInstruction::instruction_size); 1341 } 1342 1343 //============================================================================= 1344 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1345 1346 int ConstantTable::calculate_table_base_offset() const { 1347 return 0; // absolute addressing, no offset 1348 } 1349 1350 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1351 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1352 ShouldNotReachHere(); 1353 } 1354 1355 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 1356 // Empty encoding 1357 } 1358 1359 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1360 return 0; 1361 } 1362 1363 #ifndef PRODUCT 1364 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1365 assert_cond(st != nullptr); 1366 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1367 } 1368 #endif 1369 1370 #ifndef PRODUCT 1371 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1372 assert_cond(st != nullptr && ra_ != nullptr); 1373 Compile* C = ra_->C; 1374 1375 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1376 1377 if (C->output()->need_stack_bang(framesize)) { 1378 st->print("# stack bang size=%d\n\t", framesize); 1379 } 1380 1381 st->print("sd fp, [sp, #%d]\n\t", - 2 * wordSize); 1382 st->print("sd ra, [sp, #%d]\n\t", - wordSize); 1383 if (PreserveFramePointer) { st->print("sub fp, sp, #%d\n\t", 2 * wordSize); } 1384 st->print("sub sp, sp, #%d\n\t", framesize); 1385 1386 if (C->stub_function() == nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 1387 st->print("ld t0, [guard]\n\t"); 1388 st->print("membar LoadLoad\n\t"); 1389 st->print("ld t1, [xthread, #thread_disarmed_guard_value_offset]\n\t"); 1390 st->print("beq t0, t1, skip\n\t"); 1391 st->print("jalr #nmethod_entry_barrier_stub\n\t"); 1392 st->print("j skip\n\t"); 1393 st->print("guard: int\n\t"); 1394 st->print("skip:\n\t"); 1395 } 1396 } 1397 #endif 1398 1399 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1400 assert_cond(ra_ != nullptr); 1401 Compile* C = ra_->C; 1402 1403 // n.b. frame size includes space for return pc and fp 1404 const int framesize = C->output()->frame_size_in_bytes(); 1405 1406 // insert a nop at the start of the prolog so we can patch in a 1407 // branch if we need to invalidate the method later 1408 { 1409 Assembler::IncompressibleRegion ir(masm); // keep the nop as 4 bytes for patching. 1410 MacroAssembler::assert_alignment(__ pc()); 1411 __ nop(); // 4 bytes 1412 } 1413 1414 assert_cond(C != nullptr); 1415 1416 if (C->clinit_barrier_on_entry()) { 1417 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 1418 1419 Label L_skip_barrier; 1420 1421 __ mov_metadata(t1, C->method()->holder()->constant_encoding()); 1422 __ clinit_barrier(t1, t0, &L_skip_barrier); 1423 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); 1424 __ bind(L_skip_barrier); 1425 } 1426 1427 int bangsize = C->output()->bang_size_in_bytes(); 1428 if (C->output()->need_stack_bang(bangsize)) { 1429 __ generate_stack_overflow_check(bangsize); 1430 } 1431 1432 __ build_frame(framesize); 1433 1434 if (C->stub_function() == nullptr) { 1435 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); 1436 if (BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 1437 // Dummy labels for just measuring the code size 1438 Label dummy_slow_path; 1439 Label dummy_continuation; 1440 Label dummy_guard; 1441 Label* slow_path = &dummy_slow_path; 1442 Label* continuation = &dummy_continuation; 1443 Label* guard = &dummy_guard; 1444 if (!Compile::current()->output()->in_scratch_emit_size()) { 1445 // Use real labels from actual stub when not emitting code for purpose of measuring its size 1446 C2EntryBarrierStub* stub = new (Compile::current()->comp_arena()) C2EntryBarrierStub(); 1447 Compile::current()->output()->add_stub(stub); 1448 slow_path = &stub->entry(); 1449 continuation = &stub->continuation(); 1450 guard = &stub->guard(); 1451 } 1452 // In the C2 code, we move the non-hot part of nmethod entry barriers out-of-line to a stub. 1453 bs->nmethod_entry_barrier(masm, slow_path, continuation, guard); 1454 } 1455 } 1456 1457 if (VerifyStackAtCalls) { 1458 Unimplemented(); 1459 } 1460 1461 C->output()->set_frame_complete(__ offset()); 1462 1463 if (C->has_mach_constant_base_node()) { 1464 // NOTE: We set the table base offset here because users might be 1465 // emitted before MachConstantBaseNode. 1466 ConstantTable& constant_table = C->output()->constant_table(); 1467 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1468 } 1469 } 1470 1471 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1472 { 1473 assert_cond(ra_ != nullptr); 1474 return MachNode::size(ra_); // too many variables; just compute it 1475 // the hard way 1476 } 1477 1478 int MachPrologNode::reloc() const 1479 { 1480 return 0; 1481 } 1482 1483 //============================================================================= 1484 1485 #ifndef PRODUCT 1486 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1487 assert_cond(st != nullptr && ra_ != nullptr); 1488 Compile* C = ra_->C; 1489 assert_cond(C != nullptr); 1490 int framesize = C->output()->frame_size_in_bytes(); 1491 1492 st->print("# pop frame %d\n\t", framesize); 1493 1494 if (framesize == 0) { 1495 st->print("ld ra, [sp,#%d]\n\t", (2 * wordSize)); 1496 st->print("ld fp, [sp,#%d]\n\t", (3 * wordSize)); 1497 st->print("add sp, sp, #%d\n\t", (2 * wordSize)); 1498 } else { 1499 st->print("add sp, sp, #%d\n\t", framesize); 1500 st->print("ld ra, [sp,#%d]\n\t", - 2 * wordSize); 1501 st->print("ld fp, [sp,#%d]\n\t", - wordSize); 1502 } 1503 1504 if (do_polling() && C->is_method_compilation()) { 1505 st->print("# test polling word\n\t"); 1506 st->print("ld t0, [xthread,#%d]\n\t", in_bytes(JavaThread::polling_word_offset())); 1507 st->print("bgtu sp, t0, #slow_path"); 1508 } 1509 } 1510 #endif 1511 1512 void MachEpilogNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1513 assert_cond(ra_ != nullptr); 1514 Compile* C = ra_->C; 1515 assert_cond(C != nullptr); 1516 int framesize = C->output()->frame_size_in_bytes(); 1517 1518 __ remove_frame(framesize); 1519 1520 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1521 __ reserved_stack_check(); 1522 } 1523 1524 if (do_polling() && C->is_method_compilation()) { 1525 Label dummy_label; 1526 Label* code_stub = &dummy_label; 1527 if (!C->output()->in_scratch_emit_size()) { 1528 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1529 C->output()->add_stub(stub); 1530 code_stub = &stub->entry(); 1531 } 1532 __ relocate(relocInfo::poll_return_type); 1533 __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); 1534 } 1535 } 1536 1537 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1538 assert_cond(ra_ != nullptr); 1539 // Variable size. Determine dynamically. 1540 return MachNode::size(ra_); 1541 } 1542 1543 int MachEpilogNode::reloc() const { 1544 // Return number of relocatable values contained in this instruction. 1545 return 1; // 1 for polling page. 1546 } 1547 const Pipeline * MachEpilogNode::pipeline() const { 1548 return MachNode::pipeline_class(); 1549 } 1550 1551 //============================================================================= 1552 1553 // Figure out which register class each belongs in: rc_int, rc_float or 1554 // rc_stack. 1555 enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack }; 1556 1557 static enum RC rc_class(OptoReg::Name reg) { 1558 1559 if (reg == OptoReg::Bad) { 1560 return rc_bad; 1561 } 1562 1563 // we have 30 int registers * 2 halves 1564 // (t0 and t1 are omitted) 1565 int slots_of_int_registers = Register::max_slots_per_register * (Register::number_of_registers - 2); 1566 if (reg < slots_of_int_registers) { 1567 return rc_int; 1568 } 1569 1570 // we have 32 float register * 2 halves 1571 int slots_of_float_registers = FloatRegister::max_slots_per_register * FloatRegister::number_of_registers; 1572 if (reg < slots_of_int_registers + slots_of_float_registers) { 1573 return rc_float; 1574 } 1575 1576 // we have 32 vector register * 4 halves 1577 int slots_of_vector_registers = VectorRegister::max_slots_per_register * VectorRegister::number_of_registers; 1578 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_vector_registers) { 1579 return rc_vector; 1580 } 1581 1582 // Between vector regs & stack is the flags regs. 1583 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1584 1585 return rc_stack; 1586 } 1587 1588 uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1589 assert_cond(ra_ != nullptr); 1590 Compile* C = ra_->C; 1591 1592 // Get registers to move. 1593 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1594 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1595 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1596 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1597 1598 enum RC src_hi_rc = rc_class(src_hi); 1599 enum RC src_lo_rc = rc_class(src_lo); 1600 enum RC dst_hi_rc = rc_class(dst_hi); 1601 enum RC dst_lo_rc = rc_class(dst_lo); 1602 1603 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1604 1605 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) { 1606 assert((src_lo & 1) == 0 && src_lo + 1 == src_hi && 1607 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi, 1608 "expected aligned-adjacent pairs"); 1609 } 1610 1611 if (src_lo == dst_lo && src_hi == dst_hi) { 1612 return 0; // Self copy, no move. 1613 } 1614 1615 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1616 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1617 int src_offset = ra_->reg2offset(src_lo); 1618 int dst_offset = ra_->reg2offset(dst_lo); 1619 1620 if (bottom_type()->isa_vect() != nullptr) { 1621 uint ireg = ideal_reg(); 1622 if (ireg == Op_VecA && masm) { 1623 int vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); 1624 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1625 // stack to stack 1626 __ spill_copy_vector_stack_to_stack(src_offset, dst_offset, 1627 vector_reg_size_in_bytes); 1628 } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) { 1629 // vpr to stack 1630 __ spill(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo)); 1631 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) { 1632 // stack to vpr 1633 __ unspill(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo)); 1634 } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) { 1635 // vpr to vpr 1636 __ vmv1r_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo])); 1637 } else { 1638 ShouldNotReachHere(); 1639 } 1640 } else if (bottom_type()->isa_vectmask() && masm) { 1641 int vmask_size_in_bytes = Matcher::scalable_predicate_reg_slots() * 32 / 8; 1642 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1643 // stack to stack 1644 __ spill_copy_vmask_stack_to_stack(src_offset, dst_offset, 1645 vmask_size_in_bytes); 1646 } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) { 1647 // vmask to stack 1648 __ spill_vmask(as_VectorRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo)); 1649 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) { 1650 // stack to vmask 1651 __ unspill_vmask(as_VectorRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo)); 1652 } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) { 1653 // vmask to vmask 1654 __ vmv1r_v(as_VectorRegister(Matcher::_regEncode[dst_lo]), as_VectorRegister(Matcher::_regEncode[src_lo])); 1655 } else { 1656 ShouldNotReachHere(); 1657 } 1658 } 1659 } else if (masm != nullptr) { 1660 switch (src_lo_rc) { 1661 case rc_int: 1662 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1663 if (!is64 && this->ideal_reg() != Op_RegI) { // zero extended for narrow oop or klass 1664 __ zero_extend(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo]), 32); 1665 } else { 1666 __ mv(as_Register(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo])); 1667 } 1668 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1669 if (is64) { 1670 __ fmv_d_x(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1671 as_Register(Matcher::_regEncode[src_lo])); 1672 } else { 1673 __ fmv_w_x(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1674 as_Register(Matcher::_regEncode[src_lo])); 1675 } 1676 } else { // gpr --> stack spill 1677 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1678 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 1679 } 1680 break; 1681 case rc_float: 1682 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1683 if (is64) { 1684 __ fmv_x_d(as_Register(Matcher::_regEncode[dst_lo]), 1685 as_FloatRegister(Matcher::_regEncode[src_lo])); 1686 } else { 1687 __ fmv_x_w(as_Register(Matcher::_regEncode[dst_lo]), 1688 as_FloatRegister(Matcher::_regEncode[src_lo])); 1689 } 1690 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1691 if (is64) { 1692 __ fmv_d(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1693 as_FloatRegister(Matcher::_regEncode[src_lo])); 1694 } else { 1695 __ fmv_s(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1696 as_FloatRegister(Matcher::_regEncode[src_lo])); 1697 } 1698 } else { // fpr --> stack spill 1699 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1700 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1701 is64, dst_offset); 1702 } 1703 break; 1704 case rc_stack: 1705 if (dst_lo_rc == rc_int) { // stack --> gpr load 1706 if (this->ideal_reg() == Op_RegI) { 1707 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1708 } else { // // zero extended for narrow oop or klass 1709 __ unspillu(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 1710 } 1711 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1712 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1713 is64, src_offset); 1714 } else { // stack --> stack copy 1715 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1716 if (this->ideal_reg() == Op_RegI) { 1717 __ unspill(t0, is64, src_offset); 1718 } else { // zero extended for narrow oop or klass 1719 __ unspillu(t0, is64, src_offset); 1720 } 1721 __ spill(t0, is64, dst_offset); 1722 } 1723 break; 1724 default: 1725 ShouldNotReachHere(); 1726 } 1727 } 1728 1729 if (st != nullptr) { 1730 st->print("spill "); 1731 if (src_lo_rc == rc_stack) { 1732 st->print("[sp, #%d] -> ", src_offset); 1733 } else { 1734 st->print("%s -> ", Matcher::regName[src_lo]); 1735 } 1736 if (dst_lo_rc == rc_stack) { 1737 st->print("[sp, #%d]", dst_offset); 1738 } else { 1739 st->print("%s", Matcher::regName[dst_lo]); 1740 } 1741 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 1742 int vsize = 0; 1743 if (ideal_reg() == Op_VecA) { 1744 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; 1745 } else { 1746 ShouldNotReachHere(); 1747 } 1748 st->print("\t# vector spill size = %d", vsize); 1749 } else if (ideal_reg() == Op_RegVectMask) { 1750 assert(Matcher::supports_scalable_vector(), "bad register type for spill"); 1751 int vsize = Matcher::scalable_predicate_reg_slots() * 32; 1752 st->print("\t# vmask spill size = %d", vsize); 1753 } else { 1754 st->print("\t# spill size = %d", is64 ? 64 : 32); 1755 } 1756 } 1757 1758 return 0; 1759 } 1760 1761 #ifndef PRODUCT 1762 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1763 if (ra_ == nullptr) { 1764 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1765 } else { 1766 implementation(nullptr, ra_, false, st); 1767 } 1768 } 1769 #endif 1770 1771 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1772 implementation(masm, ra_, false, nullptr); 1773 } 1774 1775 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1776 return MachNode::size(ra_); 1777 } 1778 1779 //============================================================================= 1780 1781 #ifndef PRODUCT 1782 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1783 assert_cond(ra_ != nullptr && st != nullptr); 1784 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1785 int reg = ra_->get_reg_first(this); 1786 st->print("add %s, sp, #%d\t# box lock", 1787 Matcher::regName[reg], offset); 1788 } 1789 #endif 1790 1791 void BoxLockNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1792 Assembler::IncompressibleRegion ir(masm); // Fixed length: see BoxLockNode::size() 1793 1794 assert_cond(ra_ != nullptr); 1795 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1796 int reg = ra_->get_encode(this); 1797 1798 if (Assembler::is_simm12(offset)) { 1799 __ addi(as_Register(reg), sp, offset); 1800 } else { 1801 __ li32(t0, offset); 1802 __ add(as_Register(reg), sp, t0); 1803 } 1804 } 1805 1806 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1807 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1808 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1809 1810 if (Assembler::is_simm12(offset)) { 1811 return NativeInstruction::instruction_size; 1812 } else { 1813 return 3 * NativeInstruction::instruction_size; // lui + addiw + add; 1814 } 1815 } 1816 1817 //============================================================================= 1818 1819 #ifndef PRODUCT 1820 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1821 { 1822 assert_cond(st != nullptr); 1823 st->print_cr("# MachUEPNode"); 1824 if (UseCompressedClassPointers) { 1825 st->print_cr("\tlwu t0, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1826 st->print_cr("\tlwu t2, [t1 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 1827 } else { 1828 st->print_cr("\tld t0, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1829 st->print_cr("\tld t2, [t1 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 1830 } 1831 st->print_cr("\tbeq t0, t2, ic_hit"); 1832 st->print_cr("\tj, SharedRuntime::_ic_miss_stub\t # Inline cache check"); 1833 st->print_cr("\tic_hit:"); 1834 } 1835 #endif 1836 1837 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1838 { 1839 // This is the unverified entry point. 1840 __ ic_check(CodeEntryAlignment); 1841 1842 // Verified entry point must be properly 4 bytes aligned for patching by NativeJump::patch_verified_entry(). 1843 // ic_check() aligns to CodeEntryAlignment >= InteriorEntryAlignment(min 16) > NativeInstruction::instruction_size(4). 1844 assert(((__ offset()) % CodeEntryAlignment) == 0, "Misaligned verified entry point"); 1845 } 1846 1847 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1848 { 1849 assert_cond(ra_ != nullptr); 1850 return MachNode::size(ra_); 1851 } 1852 1853 // REQUIRED EMIT CODE 1854 1855 //============================================================================= 1856 1857 // Emit exception handler code. 1858 int HandlerImpl::emit_exception_handler(C2_MacroAssembler* masm) 1859 { 1860 // auipc t0, #exception_blob_entry_point 1861 // jr (offset)t0 1862 // Note that the code buffer's insts_mark is always relative to insts. 1863 // That's why we must use the macroassembler to generate a handler. 1864 address base = __ start_a_stub(size_exception_handler()); 1865 if (base == nullptr) { 1866 ciEnv::current()->record_failure("CodeCache is full"); 1867 return 0; // CodeBuffer::expand failed 1868 } 1869 int offset = __ offset(); 1870 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1871 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1872 __ end_a_stub(); 1873 return offset; 1874 } 1875 1876 // Emit deopt handler code. 1877 int HandlerImpl::emit_deopt_handler(C2_MacroAssembler* masm) 1878 { 1879 address base = __ start_a_stub(size_deopt_handler()); 1880 if (base == nullptr) { 1881 ciEnv::current()->record_failure("CodeCache is full"); 1882 return 0; // CodeBuffer::expand failed 1883 } 1884 int offset = __ offset(); 1885 1886 __ auipc(ra, 0); 1887 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1888 1889 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1890 __ end_a_stub(); 1891 return offset; 1892 1893 } 1894 // REQUIRED MATCHER CODE 1895 1896 //============================================================================= 1897 1898 bool Matcher::match_rule_supported(int opcode) { 1899 if (!has_match_rule(opcode)) { 1900 return false; 1901 } 1902 1903 switch (opcode) { 1904 case Op_OnSpinWait: 1905 return VM_Version::supports_on_spin_wait(); 1906 case Op_CacheWB: // fall through 1907 case Op_CacheWBPreSync: // fall through 1908 case Op_CacheWBPostSync: 1909 if (!VM_Version::supports_data_cache_line_flush()) { 1910 return false; 1911 } 1912 break; 1913 1914 case Op_ExpandBits: // fall through 1915 case Op_CompressBits: // fall through 1916 guarantee(UseRVV == (MaxVectorSize >= 16), "UseRVV and MaxVectorSize not matched"); 1917 case Op_StrCompressedCopy: // fall through 1918 case Op_StrInflatedCopy: // fall through 1919 case Op_CountPositives: // fall through 1920 case Op_EncodeISOArray: 1921 return UseRVV; 1922 1923 case Op_PopCountI: 1924 case Op_PopCountL: 1925 return UsePopCountInstruction; 1926 1927 case Op_ReverseBytesI: 1928 case Op_ReverseBytesL: 1929 case Op_ReverseBytesS: 1930 case Op_ReverseBytesUS: 1931 case Op_RotateRight: 1932 case Op_RotateLeft: 1933 case Op_CountLeadingZerosI: 1934 case Op_CountLeadingZerosL: 1935 case Op_CountTrailingZerosI: 1936 case Op_CountTrailingZerosL: 1937 return UseZbb; 1938 1939 case Op_FmaF: 1940 case Op_FmaD: 1941 case Op_FmaVF: 1942 case Op_FmaVD: 1943 return UseFMA; 1944 1945 case Op_ConvHF2F: 1946 case Op_ConvF2HF: 1947 return UseZfh; 1948 } 1949 1950 return true; // Per default match rules are supported. 1951 } 1952 1953 const RegMask* Matcher::predicate_reg_mask(void) { 1954 return &_VMASK_REG_mask; 1955 } 1956 1957 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 1958 return new TypeVectMask(elemTy, length); 1959 } 1960 1961 // Vector calling convention not yet implemented. 1962 bool Matcher::supports_vector_calling_convention(void) { 1963 return false; 1964 } 1965 1966 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1967 Unimplemented(); 1968 return OptoRegPair(0, 0); 1969 } 1970 1971 // Is this branch offset short enough that a short branch can be used? 1972 // 1973 // NOTE: If the platform does not provide any short branch variants, then 1974 // this method should return false for offset 0. 1975 // |---label(L1)-----| 1976 // |-----------------| 1977 // |-----------------|----------eq: float------------------- 1978 // |-----------------| // far_cmpD_branch | cmpD_branch 1979 // |------- ---------| feq; | feq; 1980 // |-far_cmpD_branch-| beqz done; | bnez L; 1981 // |-----------------| j L; | 1982 // |-----------------| bind(done); | 1983 // |-----------------|-------------------------------------- 1984 // |-----------------| // so shortBrSize = br_size - 4; 1985 // |-----------------| // so offs = offset - shortBrSize + 4; 1986 // |---label(L2)-----| 1987 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1988 // The passed offset is relative to address of the branch. 1989 int shortBrSize = br_size - 4; 1990 int offs = offset - shortBrSize + 4; 1991 return (-4096 <= offs && offs < 4096); 1992 } 1993 1994 // Vector width in bytes. 1995 int Matcher::vector_width_in_bytes(BasicType bt) { 1996 if (UseRVV) { 1997 // The MaxVectorSize should have been set by detecting RVV max vector register size when check UseRVV. 1998 // MaxVectorSize == VM_Version::_initial_vector_length 1999 int size = MaxVectorSize; 2000 // Minimum 2 values in vector 2001 if (size < 2 * type2aelembytes(bt)) size = 0; 2002 // But never < 4 2003 if (size < 4) size = 0; 2004 return size; 2005 } 2006 return 0; 2007 } 2008 2009 // Limits on vector size (number of elements) loaded into vector. 2010 int Matcher::max_vector_size(const BasicType bt) { 2011 return vector_width_in_bytes(bt) / type2aelembytes(bt); 2012 } 2013 2014 int Matcher::min_vector_size(const BasicType bt) { 2015 int max_size = max_vector_size(bt); 2016 // Limit the min vector size to 8 bytes. 2017 int size = 8 / type2aelembytes(bt); 2018 if (bt == T_BYTE) { 2019 // To support vector api shuffle/rearrange. 2020 size = 4; 2021 } else if (bt == T_BOOLEAN) { 2022 // To support vector api load/store mask. 2023 size = 2; 2024 } 2025 if (size < 2) size = 2; 2026 return MIN2(size, max_size); 2027 } 2028 2029 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) { 2030 return Matcher::max_vector_size(bt); 2031 } 2032 2033 // Vector ideal reg. 2034 uint Matcher::vector_ideal_reg(int len) { 2035 assert(MaxVectorSize >= len, ""); 2036 if (UseRVV) { 2037 return Op_VecA; 2038 } 2039 2040 ShouldNotReachHere(); 2041 return 0; 2042 } 2043 2044 int Matcher::scalable_vector_reg_size(const BasicType bt) { 2045 return Matcher::max_vector_size(bt); 2046 } 2047 2048 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { 2049 ShouldNotReachHere(); // generic vector operands not supported 2050 return nullptr; 2051 } 2052 2053 bool Matcher::is_reg2reg_move(MachNode* m) { 2054 ShouldNotReachHere(); // generic vector operands not supported 2055 return false; 2056 } 2057 2058 bool Matcher::is_generic_vector(MachOper* opnd) { 2059 ShouldNotReachHere(); // generic vector operands not supported 2060 return false; 2061 } 2062 2063 // Return whether or not this register is ever used as an argument. 2064 // This function is used on startup to build the trampoline stubs in 2065 // generateOptoStub. Registers not mentioned will be killed by the VM 2066 // call in the trampoline, and arguments in those registers not be 2067 // available to the callee. 2068 bool Matcher::can_be_java_arg(int reg) 2069 { 2070 return 2071 reg == R10_num || reg == R10_H_num || 2072 reg == R11_num || reg == R11_H_num || 2073 reg == R12_num || reg == R12_H_num || 2074 reg == R13_num || reg == R13_H_num || 2075 reg == R14_num || reg == R14_H_num || 2076 reg == R15_num || reg == R15_H_num || 2077 reg == R16_num || reg == R16_H_num || 2078 reg == R17_num || reg == R17_H_num || 2079 reg == F10_num || reg == F10_H_num || 2080 reg == F11_num || reg == F11_H_num || 2081 reg == F12_num || reg == F12_H_num || 2082 reg == F13_num || reg == F13_H_num || 2083 reg == F14_num || reg == F14_H_num || 2084 reg == F15_num || reg == F15_H_num || 2085 reg == F16_num || reg == F16_H_num || 2086 reg == F17_num || reg == F17_H_num; 2087 } 2088 2089 bool Matcher::is_spillable_arg(int reg) 2090 { 2091 return can_be_java_arg(reg); 2092 } 2093 2094 uint Matcher::int_pressure_limit() 2095 { 2096 // A derived pointer is live at CallNode and then is flagged by RA 2097 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip 2098 // derived pointers and lastly fail to spill after reaching maximum 2099 // number of iterations. Lowering the default pressure threshold to 2100 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become 2101 // a high register pressure area of the code so that split_DEF can 2102 // generate DefinitionSpillCopy for the derived pointer. 2103 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; 2104 if (!PreserveFramePointer) { 2105 // When PreserveFramePointer is off, frame pointer is allocatable, 2106 // but different from other SOC registers, it is excluded from 2107 // fatproj's mask because its save type is No-Save. Decrease 1 to 2108 // ensure high pressure at fatproj when PreserveFramePointer is off. 2109 // See check_pressure_at_fatproj(). 2110 default_int_pressure_threshold--; 2111 } 2112 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; 2113 } 2114 2115 uint Matcher::float_pressure_limit() 2116 { 2117 // _FLOAT_REG_mask is generated by adlc from the float_reg register class. 2118 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; 2119 } 2120 2121 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2122 return false; 2123 } 2124 2125 RegMask Matcher::divI_proj_mask() { 2126 ShouldNotReachHere(); 2127 return RegMask(); 2128 } 2129 2130 // Register for MODI projection of divmodI. 2131 RegMask Matcher::modI_proj_mask() { 2132 ShouldNotReachHere(); 2133 return RegMask(); 2134 } 2135 2136 // Register for DIVL projection of divmodL. 2137 RegMask Matcher::divL_proj_mask() { 2138 ShouldNotReachHere(); 2139 return RegMask(); 2140 } 2141 2142 // Register for MODL projection of divmodL. 2143 RegMask Matcher::modL_proj_mask() { 2144 ShouldNotReachHere(); 2145 return RegMask(); 2146 } 2147 2148 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2149 return FP_REG_mask(); 2150 } 2151 2152 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2153 assert_cond(addp != nullptr); 2154 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2155 Node* u = addp->fast_out(i); 2156 if (u != nullptr && u->is_Mem()) { 2157 int opsize = u->as_Mem()->memory_size(); 2158 assert(opsize > 0, "unexpected memory operand size"); 2159 if (u->as_Mem()->memory_size() != (1 << shift)) { 2160 return false; 2161 } 2162 } 2163 } 2164 return true; 2165 } 2166 2167 // Binary src (Replicate scalar/immediate) 2168 static bool is_vector_scalar_bitwise_pattern(Node* n, Node* m) { 2169 if (n == nullptr || m == nullptr) { 2170 return false; 2171 } 2172 2173 if (m->Opcode() != Op_Replicate) { 2174 return false; 2175 } 2176 2177 switch (n->Opcode()) { 2178 case Op_AndV: 2179 case Op_OrV: 2180 case Op_XorV: 2181 case Op_AddVB: 2182 case Op_AddVS: 2183 case Op_AddVI: 2184 case Op_AddVL: 2185 case Op_SubVB: 2186 case Op_SubVS: 2187 case Op_SubVI: 2188 case Op_SubVL: 2189 case Op_MulVB: 2190 case Op_MulVS: 2191 case Op_MulVI: 2192 case Op_MulVL: { 2193 return true; 2194 } 2195 default: 2196 return false; 2197 } 2198 } 2199 2200 // (XorV src (Replicate m1)) 2201 // (XorVMask src (MaskAll m1)) 2202 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) { 2203 if (n != nullptr && m != nullptr) { 2204 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) && 2205 VectorNode::is_all_ones_vector(m); 2206 } 2207 return false; 2208 } 2209 2210 // Should the Matcher clone input 'm' of node 'n'? 2211 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2212 assert_cond(m != nullptr); 2213 if (is_vshift_con_pattern(n, m) || // ShiftV src (ShiftCntV con) 2214 is_vector_bitwise_not_pattern(n, m) || 2215 is_vector_scalar_bitwise_pattern(n, m)) { 2216 mstack.push(m, Visit); 2217 return true; 2218 } 2219 return false; 2220 } 2221 2222 // Should the Matcher clone shifts on addressing modes, expecting them 2223 // to be subsumed into complex addressing expressions or compute them 2224 // into registers? 2225 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2226 return clone_base_plus_offset_address(m, mstack, address_visited); 2227 } 2228 2229 %} 2230 2231 2232 2233 //----------ENCODING BLOCK----------------------------------------------------- 2234 // This block specifies the encoding classes used by the compiler to 2235 // output byte streams. Encoding classes are parameterized macros 2236 // used by Machine Instruction Nodes in order to generate the bit 2237 // encoding of the instruction. Operands specify their base encoding 2238 // interface with the interface keyword. There are currently 2239 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2240 // COND_INTER. REG_INTER causes an operand to generate a function 2241 // which returns its register number when queried. CONST_INTER causes 2242 // an operand to generate a function which returns the value of the 2243 // constant when queried. MEMORY_INTER causes an operand to generate 2244 // four functions which return the Base Register, the Index Register, 2245 // the Scale Value, and the Offset Value of the operand when queried. 2246 // COND_INTER causes an operand to generate six functions which return 2247 // the encoding code (ie - encoding bits for the instruction) 2248 // associated with each basic boolean condition for a conditional 2249 // instruction. 2250 // 2251 // Instructions specify two basic values for encoding. Again, a 2252 // function is available to check if the constant displacement is an 2253 // oop. They use the ins_encode keyword to specify their encoding 2254 // classes (which must be a sequence of enc_class names, and their 2255 // parameters, specified in the encoding block), and they use the 2256 // opcode keyword to specify, in order, their primary, secondary, and 2257 // tertiary opcode. Only the opcode sections which a particular 2258 // instruction needs for encoding need to be specified. 2259 encode %{ 2260 // BEGIN Non-volatile memory access 2261 2262 enc_class riscv_enc_mov_imm(iRegIorL dst, immIorL src) %{ 2263 int64_t con = (int64_t)$src$$constant; 2264 Register dst_reg = as_Register($dst$$reg); 2265 __ mv(dst_reg, con); 2266 %} 2267 2268 enc_class riscv_enc_mov_p(iRegP dst, immP src) %{ 2269 Register dst_reg = as_Register($dst$$reg); 2270 address con = (address)$src$$constant; 2271 if (con == nullptr || con == (address)1) { 2272 ShouldNotReachHere(); 2273 } else { 2274 relocInfo::relocType rtype = $src->constant_reloc(); 2275 if (rtype == relocInfo::oop_type) { 2276 __ movoop(dst_reg, (jobject)con); 2277 } else if (rtype == relocInfo::metadata_type) { 2278 __ mov_metadata(dst_reg, (Metadata*)con); 2279 } else { 2280 assert(rtype == relocInfo::none, "unexpected reloc type"); 2281 __ mv(dst_reg, $src$$constant); 2282 } 2283 } 2284 %} 2285 2286 enc_class riscv_enc_mov_p1(iRegP dst) %{ 2287 Register dst_reg = as_Register($dst$$reg); 2288 __ mv(dst_reg, 1); 2289 %} 2290 2291 enc_class riscv_enc_mov_byte_map_base(iRegP dst) %{ 2292 __ load_byte_map_base($dst$$Register); 2293 %} 2294 2295 enc_class riscv_enc_mov_n(iRegN dst, immN src) %{ 2296 Register dst_reg = as_Register($dst$$reg); 2297 address con = (address)$src$$constant; 2298 if (con == nullptr) { 2299 ShouldNotReachHere(); 2300 } else { 2301 relocInfo::relocType rtype = $src->constant_reloc(); 2302 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 2303 __ set_narrow_oop(dst_reg, (jobject)con); 2304 } 2305 %} 2306 2307 enc_class riscv_enc_mov_zero(iRegNorP dst) %{ 2308 Register dst_reg = as_Register($dst$$reg); 2309 __ mv(dst_reg, zr); 2310 %} 2311 2312 enc_class riscv_enc_mov_nk(iRegN dst, immNKlass src) %{ 2313 Register dst_reg = as_Register($dst$$reg); 2314 address con = (address)$src$$constant; 2315 if (con == nullptr) { 2316 ShouldNotReachHere(); 2317 } else { 2318 relocInfo::relocType rtype = $src->constant_reloc(); 2319 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 2320 __ set_narrow_klass(dst_reg, (Klass *)con); 2321 } 2322 %} 2323 2324 enc_class riscv_enc_cmpxchgw(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ 2325 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 2326 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 2327 /*result as bool*/ true); 2328 %} 2329 2330 enc_class riscv_enc_cmpxchgn(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ 2331 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 2332 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 2333 /*result as bool*/ true); 2334 %} 2335 2336 enc_class riscv_enc_cmpxchg(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ 2337 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 2338 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 2339 /*result as bool*/ true); 2340 %} 2341 2342 enc_class riscv_enc_cmpxchgw_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ 2343 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 2344 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 2345 /*result as bool*/ true); 2346 %} 2347 2348 enc_class riscv_enc_cmpxchgn_acq(iRegINoSp res, memory mem, iRegI oldval, iRegI newval) %{ 2349 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 2350 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 2351 /*result as bool*/ true); 2352 %} 2353 2354 enc_class riscv_enc_cmpxchg_acq(iRegINoSp res, memory mem, iRegL oldval, iRegL newval) %{ 2355 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 2356 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 2357 /*result as bool*/ true); 2358 %} 2359 2360 // compare and branch instruction encodings 2361 2362 enc_class riscv_enc_j(label lbl) %{ 2363 Label* L = $lbl$$label; 2364 __ j(*L); 2365 %} 2366 2367 enc_class riscv_enc_far_cmpULtGe_imm0_branch(cmpOpULtGe cmp, iRegIorL op1, label lbl) %{ 2368 Label* L = $lbl$$label; 2369 switch ($cmp$$cmpcode) { 2370 case(BoolTest::ge): 2371 __ j(*L); 2372 break; 2373 case(BoolTest::lt): 2374 break; 2375 default: 2376 Unimplemented(); 2377 } 2378 %} 2379 2380 // call instruction encodings 2381 2382 enc_class riscv_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) %{ 2383 Register sub_reg = as_Register($sub$$reg); 2384 Register super_reg = as_Register($super$$reg); 2385 Register temp_reg = as_Register($temp$$reg); 2386 Register result_reg = as_Register($result$$reg); 2387 Register cr_reg = t1; 2388 2389 Label miss; 2390 Label done; 2391 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 2392 nullptr, &miss); 2393 if ($primary) { 2394 __ mv(result_reg, zr); 2395 } else { 2396 __ mv(cr_reg, zr); 2397 __ j(done); 2398 } 2399 2400 __ bind(miss); 2401 if (!$primary) { 2402 __ mv(cr_reg, 1); 2403 } 2404 2405 __ bind(done); 2406 %} 2407 2408 enc_class riscv_enc_java_static_call(method meth) %{ 2409 Assembler::IncompressibleRegion ir(masm); // Fixed length: see ret_addr_offset 2410 2411 address addr = (address)$meth$$method; 2412 address call = nullptr; 2413 assert_cond(addr != nullptr); 2414 if (!_method) { 2415 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 2416 call = __ reloc_call(Address(addr, relocInfo::runtime_call_type)); 2417 if (call == nullptr) { 2418 ciEnv::current()->record_failure("CodeCache is full"); 2419 return; 2420 } 2421 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 2422 // The NOP here is purely to ensure that eliding a call to 2423 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 2424 __ nop(); 2425 if (!UseTrampolines) { 2426 __ nop(); 2427 __ nop(); 2428 } 2429 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 2430 } else { 2431 int method_index = resolved_method_index(masm); 2432 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2433 : static_call_Relocation::spec(method_index); 2434 call = __ reloc_call(Address(addr, rspec)); 2435 if (call == nullptr) { 2436 ciEnv::current()->record_failure("CodeCache is full"); 2437 return; 2438 } 2439 2440 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 2441 // Calls of the same statically bound method can share 2442 // a stub to the interpreter. 2443 __ code()->shared_stub_to_interp_for(_method, call - (__ begin())); 2444 } else { 2445 // Emit stub for static call 2446 address stub = CompiledDirectCall::emit_to_interp_stub(masm, call); 2447 if (stub == nullptr) { 2448 ciEnv::current()->record_failure("CodeCache is full"); 2449 return; 2450 } 2451 } 2452 } 2453 2454 __ post_call_nop(); 2455 %} 2456 2457 enc_class riscv_enc_java_dynamic_call(method meth) %{ 2458 Assembler::IncompressibleRegion ir(masm); // Fixed length: see ret_addr_offset 2459 int method_index = resolved_method_index(masm); 2460 address call = __ ic_call((address)$meth$$method, method_index); 2461 if (call == nullptr) { 2462 ciEnv::current()->record_failure("CodeCache is full"); 2463 return; 2464 } 2465 2466 __ post_call_nop(); 2467 %} 2468 2469 enc_class riscv_enc_call_epilog() %{ 2470 if (VerifyStackAtCalls) { 2471 // Check that stack depth is unchanged: find majik cookie on stack 2472 __ call_Unimplemented(); 2473 } 2474 %} 2475 2476 enc_class riscv_enc_java_to_runtime(method meth) %{ 2477 Assembler::IncompressibleRegion ir(masm); // Fixed length: see ret_addr_offset 2478 2479 // some calls to generated routines (arraycopy code) are scheduled 2480 // by C2 as runtime calls. if so we can call them using a jr (they 2481 // will be in a reachable segment) otherwise we have to use a jalr 2482 // which loads the absolute address into a register. 2483 address entry = (address)$meth$$method; 2484 CodeBlob *cb = CodeCache::find_blob(entry); 2485 if (cb != nullptr) { 2486 address call = __ reloc_call(Address(entry, relocInfo::runtime_call_type)); 2487 if (call == nullptr) { 2488 ciEnv::current()->record_failure("CodeCache is full"); 2489 return; 2490 } 2491 __ post_call_nop(); 2492 } else { 2493 Label retaddr; 2494 __ la(t1, retaddr); 2495 __ la(t0, RuntimeAddress(entry)); 2496 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 2497 __ addi(sp, sp, -2 * wordSize); 2498 __ sd(t1, Address(sp, wordSize)); 2499 __ jalr(t0); 2500 __ bind(retaddr); 2501 __ post_call_nop(); 2502 __ addi(sp, sp, 2 * wordSize); 2503 } 2504 %} 2505 2506 // arithmetic encodings 2507 2508 enc_class riscv_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 2509 Register dst_reg = as_Register($dst$$reg); 2510 Register src1_reg = as_Register($src1$$reg); 2511 Register src2_reg = as_Register($src2$$reg); 2512 __ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true); 2513 %} 2514 2515 enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{ 2516 Register dst_reg = as_Register($dst$$reg); 2517 Register src1_reg = as_Register($src1$$reg); 2518 Register src2_reg = as_Register($src2$$reg); 2519 __ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false); 2520 %} 2521 2522 enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 2523 Register dst_reg = as_Register($dst$$reg); 2524 Register src1_reg = as_Register($src1$$reg); 2525 Register src2_reg = as_Register($src2$$reg); 2526 __ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true); 2527 %} 2528 2529 enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{ 2530 Register dst_reg = as_Register($dst$$reg); 2531 Register src1_reg = as_Register($src1$$reg); 2532 Register src2_reg = as_Register($src2$$reg); 2533 __ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false); 2534 %} 2535 2536 enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 2537 Register dst_reg = as_Register($dst$$reg); 2538 Register src1_reg = as_Register($src1$$reg); 2539 Register src2_reg = as_Register($src2$$reg); 2540 __ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true); 2541 %} 2542 2543 enc_class riscv_enc_moduw(iRegI dst, iRegI src1, iRegI src2) %{ 2544 Register dst_reg = as_Register($dst$$reg); 2545 Register src1_reg = as_Register($src1$$reg); 2546 Register src2_reg = as_Register($src2$$reg); 2547 __ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false); 2548 %} 2549 2550 enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 2551 Register dst_reg = as_Register($dst$$reg); 2552 Register src1_reg = as_Register($src1$$reg); 2553 Register src2_reg = as_Register($src2$$reg); 2554 __ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true); 2555 %} 2556 2557 enc_class riscv_enc_modu(iRegI dst, iRegI src1, iRegI src2) %{ 2558 Register dst_reg = as_Register($dst$$reg); 2559 Register src1_reg = as_Register($src1$$reg); 2560 Register src2_reg = as_Register($src2$$reg); 2561 __ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false); 2562 %} 2563 2564 enc_class riscv_enc_tail_call(iRegP jump_target) %{ 2565 Register target_reg = as_Register($jump_target$$reg); 2566 __ jr(target_reg); 2567 %} 2568 2569 enc_class riscv_enc_tail_jmp(iRegP jump_target) %{ 2570 Register target_reg = as_Register($jump_target$$reg); 2571 // exception oop should be in x10 2572 // ret addr has been popped into ra 2573 // callee expects it in x13 2574 __ mv(x13, ra); 2575 __ jr(target_reg); 2576 %} 2577 2578 enc_class riscv_enc_rethrow() %{ 2579 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 2580 %} 2581 2582 enc_class riscv_enc_ret() %{ 2583 __ ret(); 2584 %} 2585 2586 %} 2587 2588 //----------FRAME-------------------------------------------------------------- 2589 // Definition of frame structure and management information. 2590 // 2591 // S T A C K L A Y O U T Allocators stack-slot number 2592 // | (to get allocators register number 2593 // G Owned by | | v add OptoReg::stack0()) 2594 // r CALLER | | 2595 // o | +--------+ pad to even-align allocators stack-slot 2596 // w V | pad0 | numbers; owned by CALLER 2597 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2598 // h ^ | in | 5 2599 // | | args | 4 Holes in incoming args owned by SELF 2600 // | | | | 3 2601 // | | +--------+ 2602 // V | | old out| Empty on Intel, window on Sparc 2603 // | old |preserve| Must be even aligned. 2604 // | SP-+--------+----> Matcher::_old_SP, even aligned 2605 // | | in | 3 area for Intel ret address 2606 // Owned by |preserve| Empty on Sparc. 2607 // SELF +--------+ 2608 // | | pad2 | 2 pad to align old SP 2609 // | +--------+ 1 2610 // | | locks | 0 2611 // | +--------+----> OptoReg::stack0(), even aligned 2612 // | | pad1 | 11 pad to align new SP 2613 // | +--------+ 2614 // | | | 10 2615 // | | spills | 9 spills 2616 // V | | 8 (pad0 slot for callee) 2617 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2618 // ^ | out | 7 2619 // | | args | 6 Holes in outgoing args owned by CALLEE 2620 // Owned by +--------+ 2621 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2622 // | new |preserve| Must be even-aligned. 2623 // | SP-+--------+----> Matcher::_new_SP, even aligned 2624 // | | | 2625 // 2626 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2627 // known from SELF's arguments and the Java calling convention. 2628 // Region 6-7 is determined per call site. 2629 // Note 2: If the calling convention leaves holes in the incoming argument 2630 // area, those holes are owned by SELF. Holes in the outgoing area 2631 // are owned by the CALLEE. Holes should not be necessary in the 2632 // incoming area, as the Java calling convention is completely under 2633 // the control of the AD file. Doubles can be sorted and packed to 2634 // avoid holes. Holes in the outgoing arguments may be necessary for 2635 // varargs C calling conventions. 2636 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2637 // even aligned with pad0 as needed. 2638 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2639 // (the latter is true on Intel but is it false on RISCV?) 2640 // region 6-11 is even aligned; it may be padded out more so that 2641 // the region from SP to FP meets the minimum stack alignment. 2642 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2643 // alignment. Region 11, pad1, may be dynamically extended so that 2644 // SP meets the minimum alignment. 2645 2646 frame %{ 2647 // These three registers define part of the calling convention 2648 // between compiled code and the interpreter. 2649 2650 // Inline Cache Register or methodOop for I2C. 2651 inline_cache_reg(R31); 2652 2653 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] 2654 cisc_spilling_operand_name(indOffset); 2655 2656 // Number of stack slots consumed by locking an object 2657 // generate Compile::sync_stack_slots 2658 // VMRegImpl::slots_per_word = wordSize / stack_slot_size = 8 / 4 = 2 2659 sync_stack_slots(1 * VMRegImpl::slots_per_word); 2660 2661 // Compiled code's Frame Pointer 2662 frame_pointer(R2); 2663 2664 // Interpreter stores its frame pointer in a register which is 2665 // stored to the stack by I2CAdaptors. 2666 // I2CAdaptors convert from interpreted java to compiled java. 2667 interpreter_frame_pointer(R8); 2668 2669 // Stack alignment requirement 2670 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2671 2672 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2673 // for calls to C. Supports the var-args backing area for register parms. 2674 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes / BytesPerInt); 2675 2676 // The after-PROLOG location of the return address. Location of 2677 // return address specifies a type (REG or STACK) and a number 2678 // representing the register number (i.e. - use a register name) or 2679 // stack slot. 2680 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2681 // Otherwise, it is above the locks and verification slot and alignment word 2682 // TODO this may well be correct but need to check why that - 2 is there 2683 // ppc port uses 0 but we definitely need to allow for fixed_slots 2684 // which folds in the space used for monitors 2685 return_addr(STACK - 2 + 2686 align_up((Compile::current()->in_preserve_stack_slots() + 2687 Compile::current()->fixed_slots()), 2688 stack_alignment_in_slots())); 2689 2690 // Location of compiled Java return values. Same as C for now. 2691 return_value 2692 %{ 2693 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2694 "only return normal values"); 2695 2696 static const int lo[Op_RegL + 1] = { // enum name 2697 0, // Op_Node 2698 0, // Op_Set 2699 R10_num, // Op_RegN 2700 R10_num, // Op_RegI 2701 R10_num, // Op_RegP 2702 F10_num, // Op_RegF 2703 F10_num, // Op_RegD 2704 R10_num // Op_RegL 2705 }; 2706 2707 static const int hi[Op_RegL + 1] = { // enum name 2708 0, // Op_Node 2709 0, // Op_Set 2710 OptoReg::Bad, // Op_RegN 2711 OptoReg::Bad, // Op_RegI 2712 R10_H_num, // Op_RegP 2713 OptoReg::Bad, // Op_RegF 2714 F10_H_num, // Op_RegD 2715 R10_H_num // Op_RegL 2716 }; 2717 2718 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2719 %} 2720 %} 2721 2722 //----------ATTRIBUTES--------------------------------------------------------- 2723 //----------Operand Attributes------------------------------------------------- 2724 op_attrib op_cost(1); // Required cost attribute 2725 2726 //----------Instruction Attributes--------------------------------------------- 2727 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute 2728 ins_attrib ins_size(32); // Required size attribute (in bits) 2729 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2730 // a non-matching short branch variant 2731 // of some long branch? 2732 ins_attrib ins_alignment(4); // Required alignment attribute (must 2733 // be a power of 2) specifies the 2734 // alignment that some part of the 2735 // instruction (not necessarily the 2736 // start) requires. If > 1, a 2737 // compute_padding() function must be 2738 // provided for the instruction 2739 2740 //----------OPERANDS----------------------------------------------------------- 2741 // Operand definitions must precede instruction definitions for correct parsing 2742 // in the ADLC because operands constitute user defined types which are used in 2743 // instruction definitions. 2744 2745 //----------Simple Operands---------------------------------------------------- 2746 2747 // Integer operands 32 bit 2748 // 32 bit immediate 2749 operand immI() 2750 %{ 2751 match(ConI); 2752 2753 op_cost(0); 2754 format %{ %} 2755 interface(CONST_INTER); 2756 %} 2757 2758 // 32 bit zero 2759 operand immI0() 2760 %{ 2761 predicate(n->get_int() == 0); 2762 match(ConI); 2763 2764 op_cost(0); 2765 format %{ %} 2766 interface(CONST_INTER); 2767 %} 2768 2769 // 32 bit unit increment 2770 operand immI_1() 2771 %{ 2772 predicate(n->get_int() == 1); 2773 match(ConI); 2774 2775 op_cost(0); 2776 format %{ %} 2777 interface(CONST_INTER); 2778 %} 2779 2780 // 32 bit unit decrement 2781 operand immI_M1() 2782 %{ 2783 predicate(n->get_int() == -1); 2784 match(ConI); 2785 2786 op_cost(0); 2787 format %{ %} 2788 interface(CONST_INTER); 2789 %} 2790 2791 // Unsigned Integer Immediate: 6-bit int, greater than 32 2792 operand uimmI6_ge32() %{ 2793 predicate(((unsigned int)(n->get_int()) < 64) && (n->get_int() >= 32)); 2794 match(ConI); 2795 op_cost(0); 2796 format %{ %} 2797 interface(CONST_INTER); 2798 %} 2799 2800 operand immI_le_4() 2801 %{ 2802 predicate(n->get_int() <= 4); 2803 match(ConI); 2804 2805 op_cost(0); 2806 format %{ %} 2807 interface(CONST_INTER); 2808 %} 2809 2810 operand immI_16() 2811 %{ 2812 predicate(n->get_int() == 16); 2813 match(ConI); 2814 op_cost(0); 2815 format %{ %} 2816 interface(CONST_INTER); 2817 %} 2818 2819 operand immI_24() 2820 %{ 2821 predicate(n->get_int() == 24); 2822 match(ConI); 2823 op_cost(0); 2824 format %{ %} 2825 interface(CONST_INTER); 2826 %} 2827 2828 operand immI_31() 2829 %{ 2830 predicate(n->get_int() == 31); 2831 match(ConI); 2832 2833 op_cost(0); 2834 format %{ %} 2835 interface(CONST_INTER); 2836 %} 2837 2838 operand immI_63() 2839 %{ 2840 predicate(n->get_int() == 63); 2841 match(ConI); 2842 2843 op_cost(0); 2844 format %{ %} 2845 interface(CONST_INTER); 2846 %} 2847 2848 // 32 bit integer valid for add immediate 2849 operand immIAdd() 2850 %{ 2851 predicate(Assembler::is_simm12((int64_t)n->get_int())); 2852 match(ConI); 2853 op_cost(0); 2854 format %{ %} 2855 interface(CONST_INTER); 2856 %} 2857 2858 // 32 bit integer valid for sub immediate 2859 operand immISub() 2860 %{ 2861 predicate(Assembler::is_simm12(-(int64_t)n->get_int())); 2862 match(ConI); 2863 op_cost(0); 2864 format %{ %} 2865 interface(CONST_INTER); 2866 %} 2867 2868 // 5 bit signed value. 2869 operand immI5() 2870 %{ 2871 predicate(n->get_int() <= 15 && n->get_int() >= -16); 2872 match(ConI); 2873 2874 op_cost(0); 2875 format %{ %} 2876 interface(CONST_INTER); 2877 %} 2878 2879 // 5 bit signed value (simm5) 2880 operand immL5() 2881 %{ 2882 predicate(n->get_long() <= 15 && n->get_long() >= -16); 2883 match(ConL); 2884 2885 op_cost(0); 2886 format %{ %} 2887 interface(CONST_INTER); 2888 %} 2889 2890 // Integer operands 64 bit 2891 // 64 bit immediate 2892 operand immL() 2893 %{ 2894 match(ConL); 2895 2896 op_cost(0); 2897 format %{ %} 2898 interface(CONST_INTER); 2899 %} 2900 2901 // 64 bit zero 2902 operand immL0() 2903 %{ 2904 predicate(n->get_long() == 0); 2905 match(ConL); 2906 2907 op_cost(0); 2908 format %{ %} 2909 interface(CONST_INTER); 2910 %} 2911 2912 // Pointer operands 2913 // Pointer Immediate 2914 operand immP() 2915 %{ 2916 match(ConP); 2917 2918 op_cost(0); 2919 format %{ %} 2920 interface(CONST_INTER); 2921 %} 2922 2923 // Null Pointer Immediate 2924 operand immP0() 2925 %{ 2926 predicate(n->get_ptr() == 0); 2927 match(ConP); 2928 2929 op_cost(0); 2930 format %{ %} 2931 interface(CONST_INTER); 2932 %} 2933 2934 // Pointer Immediate One 2935 // this is used in object initialization (initial object header) 2936 operand immP_1() 2937 %{ 2938 predicate(n->get_ptr() == 1); 2939 match(ConP); 2940 2941 op_cost(0); 2942 format %{ %} 2943 interface(CONST_INTER); 2944 %} 2945 2946 // Card Table Byte Map Base 2947 operand immByteMapBase() 2948 %{ 2949 // Get base of card map 2950 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 2951 (CardTable::CardValue*)n->get_ptr() == 2952 ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 2953 match(ConP); 2954 2955 op_cost(0); 2956 format %{ %} 2957 interface(CONST_INTER); 2958 %} 2959 2960 // Int Immediate: low 16-bit mask 2961 operand immI_16bits() 2962 %{ 2963 predicate(n->get_int() == 0xFFFF); 2964 match(ConI); 2965 op_cost(0); 2966 format %{ %} 2967 interface(CONST_INTER); 2968 %} 2969 2970 operand immIpowerOf2() %{ 2971 predicate(is_power_of_2((juint)(n->get_int()))); 2972 match(ConI); 2973 op_cost(0); 2974 format %{ %} 2975 interface(CONST_INTER); 2976 %} 2977 2978 // Long Immediate: low 32-bit mask 2979 operand immL_32bits() 2980 %{ 2981 predicate(n->get_long() == 0xFFFFFFFFL); 2982 match(ConL); 2983 op_cost(0); 2984 format %{ %} 2985 interface(CONST_INTER); 2986 %} 2987 2988 // 64 bit unit decrement 2989 operand immL_M1() 2990 %{ 2991 predicate(n->get_long() == -1); 2992 match(ConL); 2993 2994 op_cost(0); 2995 format %{ %} 2996 interface(CONST_INTER); 2997 %} 2998 2999 3000 // 64 bit integer valid for add immediate 3001 operand immLAdd() 3002 %{ 3003 predicate(Assembler::is_simm12(n->get_long())); 3004 match(ConL); 3005 op_cost(0); 3006 format %{ %} 3007 interface(CONST_INTER); 3008 %} 3009 3010 // 64 bit integer valid for sub immediate 3011 operand immLSub() 3012 %{ 3013 predicate(Assembler::is_simm12(-(n->get_long()))); 3014 match(ConL); 3015 op_cost(0); 3016 format %{ %} 3017 interface(CONST_INTER); 3018 %} 3019 3020 // Narrow pointer operands 3021 // Narrow Pointer Immediate 3022 operand immN() 3023 %{ 3024 match(ConN); 3025 3026 op_cost(0); 3027 format %{ %} 3028 interface(CONST_INTER); 3029 %} 3030 3031 // Narrow Null Pointer Immediate 3032 operand immN0() 3033 %{ 3034 predicate(n->get_narrowcon() == 0); 3035 match(ConN); 3036 3037 op_cost(0); 3038 format %{ %} 3039 interface(CONST_INTER); 3040 %} 3041 3042 operand immNKlass() 3043 %{ 3044 match(ConNKlass); 3045 3046 op_cost(0); 3047 format %{ %} 3048 interface(CONST_INTER); 3049 %} 3050 3051 // Float and Double operands 3052 // Double Immediate 3053 operand immD() 3054 %{ 3055 match(ConD); 3056 op_cost(0); 3057 format %{ %} 3058 interface(CONST_INTER); 3059 %} 3060 3061 // Double Immediate: +0.0d 3062 operand immD0() 3063 %{ 3064 predicate(jlong_cast(n->getd()) == 0); 3065 match(ConD); 3066 3067 op_cost(0); 3068 format %{ %} 3069 interface(CONST_INTER); 3070 %} 3071 3072 // Float Immediate 3073 operand immF() 3074 %{ 3075 match(ConF); 3076 op_cost(0); 3077 format %{ %} 3078 interface(CONST_INTER); 3079 %} 3080 3081 // Float Immediate: +0.0f. 3082 operand immF0() 3083 %{ 3084 predicate(jint_cast(n->getf()) == 0); 3085 match(ConF); 3086 3087 op_cost(0); 3088 format %{ %} 3089 interface(CONST_INTER); 3090 %} 3091 3092 operand immIOffset() 3093 %{ 3094 predicate(Assembler::is_simm12(n->get_int())); 3095 match(ConI); 3096 op_cost(0); 3097 format %{ %} 3098 interface(CONST_INTER); 3099 %} 3100 3101 operand immLOffset() 3102 %{ 3103 predicate(Assembler::is_simm12(n->get_long())); 3104 match(ConL); 3105 op_cost(0); 3106 format %{ %} 3107 interface(CONST_INTER); 3108 %} 3109 3110 // Scale values 3111 operand immIScale() 3112 %{ 3113 predicate(1 <= n->get_int() && (n->get_int() <= 3)); 3114 match(ConI); 3115 3116 op_cost(0); 3117 format %{ %} 3118 interface(CONST_INTER); 3119 %} 3120 3121 // Integer 32 bit Register Operands 3122 operand iRegI() 3123 %{ 3124 constraint(ALLOC_IN_RC(any_reg32)); 3125 match(RegI); 3126 match(iRegINoSp); 3127 op_cost(0); 3128 format %{ %} 3129 interface(REG_INTER); 3130 %} 3131 3132 // Integer 32 bit Register not Special 3133 operand iRegINoSp() 3134 %{ 3135 constraint(ALLOC_IN_RC(no_special_reg32)); 3136 match(RegI); 3137 op_cost(0); 3138 format %{ %} 3139 interface(REG_INTER); 3140 %} 3141 3142 // Register R10 only 3143 operand iRegI_R10() 3144 %{ 3145 constraint(ALLOC_IN_RC(int_r10_reg)); 3146 match(RegI); 3147 match(iRegINoSp); 3148 op_cost(0); 3149 format %{ %} 3150 interface(REG_INTER); 3151 %} 3152 3153 // Register R12 only 3154 operand iRegI_R12() 3155 %{ 3156 constraint(ALLOC_IN_RC(int_r12_reg)); 3157 match(RegI); 3158 match(iRegINoSp); 3159 op_cost(0); 3160 format %{ %} 3161 interface(REG_INTER); 3162 %} 3163 3164 // Register R13 only 3165 operand iRegI_R13() 3166 %{ 3167 constraint(ALLOC_IN_RC(int_r13_reg)); 3168 match(RegI); 3169 match(iRegINoSp); 3170 op_cost(0); 3171 format %{ %} 3172 interface(REG_INTER); 3173 %} 3174 3175 // Register R14 only 3176 operand iRegI_R14() 3177 %{ 3178 constraint(ALLOC_IN_RC(int_r14_reg)); 3179 match(RegI); 3180 match(iRegINoSp); 3181 op_cost(0); 3182 format %{ %} 3183 interface(REG_INTER); 3184 %} 3185 3186 // Integer 64 bit Register Operands 3187 operand iRegL() 3188 %{ 3189 constraint(ALLOC_IN_RC(any_reg)); 3190 match(RegL); 3191 match(iRegLNoSp); 3192 op_cost(0); 3193 format %{ %} 3194 interface(REG_INTER); 3195 %} 3196 3197 // Integer 64 bit Register not Special 3198 operand iRegLNoSp() 3199 %{ 3200 constraint(ALLOC_IN_RC(no_special_reg)); 3201 match(RegL); 3202 match(iRegL_R10); 3203 format %{ %} 3204 interface(REG_INTER); 3205 %} 3206 3207 // Long 64 bit Register R29 only 3208 operand iRegL_R29() 3209 %{ 3210 constraint(ALLOC_IN_RC(r29_reg)); 3211 match(RegL); 3212 match(iRegLNoSp); 3213 op_cost(0); 3214 format %{ %} 3215 interface(REG_INTER); 3216 %} 3217 3218 // Long 64 bit Register R30 only 3219 operand iRegL_R30() 3220 %{ 3221 constraint(ALLOC_IN_RC(r30_reg)); 3222 match(RegL); 3223 match(iRegLNoSp); 3224 op_cost(0); 3225 format %{ %} 3226 interface(REG_INTER); 3227 %} 3228 3229 // Pointer Register Operands 3230 // Pointer Register 3231 operand iRegP() 3232 %{ 3233 constraint(ALLOC_IN_RC(ptr_reg)); 3234 match(RegP); 3235 match(iRegPNoSp); 3236 match(iRegP_R10); 3237 match(iRegP_R15); 3238 match(javaThread_RegP); 3239 op_cost(0); 3240 format %{ %} 3241 interface(REG_INTER); 3242 %} 3243 3244 // Pointer 64 bit Register not Special 3245 operand iRegPNoSp() 3246 %{ 3247 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 3248 match(RegP); 3249 op_cost(0); 3250 format %{ %} 3251 interface(REG_INTER); 3252 %} 3253 3254 // This operand is not allowed to use fp even if 3255 // fp is not used to hold the frame pointer. 3256 operand iRegPNoSpNoFp() 3257 %{ 3258 constraint(ALLOC_IN_RC(no_special_no_fp_ptr_reg)); 3259 match(RegP); 3260 match(iRegPNoSp); 3261 op_cost(0); 3262 format %{ %} 3263 interface(REG_INTER); 3264 %} 3265 3266 operand iRegP_R10() 3267 %{ 3268 constraint(ALLOC_IN_RC(r10_reg)); 3269 match(RegP); 3270 // match(iRegP); 3271 match(iRegPNoSp); 3272 op_cost(0); 3273 format %{ %} 3274 interface(REG_INTER); 3275 %} 3276 3277 // Pointer 64 bit Register R11 only 3278 operand iRegP_R11() 3279 %{ 3280 constraint(ALLOC_IN_RC(r11_reg)); 3281 match(RegP); 3282 match(iRegPNoSp); 3283 op_cost(0); 3284 format %{ %} 3285 interface(REG_INTER); 3286 %} 3287 3288 operand iRegP_R12() 3289 %{ 3290 constraint(ALLOC_IN_RC(r12_reg)); 3291 match(RegP); 3292 // match(iRegP); 3293 match(iRegPNoSp); 3294 op_cost(0); 3295 format %{ %} 3296 interface(REG_INTER); 3297 %} 3298 3299 // Pointer 64 bit Register R13 only 3300 operand iRegP_R13() 3301 %{ 3302 constraint(ALLOC_IN_RC(r13_reg)); 3303 match(RegP); 3304 match(iRegPNoSp); 3305 op_cost(0); 3306 format %{ %} 3307 interface(REG_INTER); 3308 %} 3309 3310 operand iRegP_R14() 3311 %{ 3312 constraint(ALLOC_IN_RC(r14_reg)); 3313 match(RegP); 3314 // match(iRegP); 3315 match(iRegPNoSp); 3316 op_cost(0); 3317 format %{ %} 3318 interface(REG_INTER); 3319 %} 3320 3321 operand iRegP_R15() 3322 %{ 3323 constraint(ALLOC_IN_RC(r15_reg)); 3324 match(RegP); 3325 // match(iRegP); 3326 match(iRegPNoSp); 3327 op_cost(0); 3328 format %{ %} 3329 interface(REG_INTER); 3330 %} 3331 3332 operand iRegP_R16() 3333 %{ 3334 constraint(ALLOC_IN_RC(r16_reg)); 3335 match(RegP); 3336 match(iRegPNoSp); 3337 op_cost(0); 3338 format %{ %} 3339 interface(REG_INTER); 3340 %} 3341 3342 // Pointer 64 bit Register R28 only 3343 operand iRegP_R28() 3344 %{ 3345 constraint(ALLOC_IN_RC(r28_reg)); 3346 match(RegP); 3347 match(iRegPNoSp); 3348 op_cost(0); 3349 format %{ %} 3350 interface(REG_INTER); 3351 %} 3352 3353 // Pointer 64 bit Register R30 only 3354 operand iRegP_R30() 3355 %{ 3356 constraint(ALLOC_IN_RC(r30_reg)); 3357 match(RegP); 3358 match(iRegPNoSp); 3359 op_cost(0); 3360 format %{ %} 3361 interface(REG_INTER); 3362 %} 3363 3364 // Pointer 64 bit Register R31 only 3365 operand iRegP_R31() 3366 %{ 3367 constraint(ALLOC_IN_RC(r31_reg)); 3368 match(RegP); 3369 match(iRegPNoSp); 3370 op_cost(0); 3371 format %{ %} 3372 interface(REG_INTER); 3373 %} 3374 3375 // Pointer Register Operands 3376 // Narrow Pointer Register 3377 operand iRegN() 3378 %{ 3379 constraint(ALLOC_IN_RC(any_reg32)); 3380 match(RegN); 3381 match(iRegNNoSp); 3382 op_cost(0); 3383 format %{ %} 3384 interface(REG_INTER); 3385 %} 3386 3387 // Integer 64 bit Register not Special 3388 operand iRegNNoSp() 3389 %{ 3390 constraint(ALLOC_IN_RC(no_special_reg32)); 3391 match(RegN); 3392 op_cost(0); 3393 format %{ %} 3394 interface(REG_INTER); 3395 %} 3396 3397 // Long 64 bit Register R10 only 3398 operand iRegL_R10() 3399 %{ 3400 constraint(ALLOC_IN_RC(r10_reg)); 3401 match(RegL); 3402 match(iRegLNoSp); 3403 op_cost(0); 3404 format %{ %} 3405 interface(REG_INTER); 3406 %} 3407 3408 // Float Register 3409 // Float register operands 3410 operand fRegF() 3411 %{ 3412 constraint(ALLOC_IN_RC(float_reg)); 3413 match(RegF); 3414 3415 op_cost(0); 3416 format %{ %} 3417 interface(REG_INTER); 3418 %} 3419 3420 // Double Register 3421 // Double register operands 3422 operand fRegD() 3423 %{ 3424 constraint(ALLOC_IN_RC(double_reg)); 3425 match(RegD); 3426 3427 op_cost(0); 3428 format %{ %} 3429 interface(REG_INTER); 3430 %} 3431 3432 // Generic vector class. This will be used for 3433 // all vector operands. 3434 operand vReg() 3435 %{ 3436 constraint(ALLOC_IN_RC(vectora_reg)); 3437 match(VecA); 3438 op_cost(0); 3439 format %{ %} 3440 interface(REG_INTER); 3441 %} 3442 3443 operand vReg_V1() 3444 %{ 3445 constraint(ALLOC_IN_RC(v1_reg)); 3446 match(VecA); 3447 match(vReg); 3448 op_cost(0); 3449 format %{ %} 3450 interface(REG_INTER); 3451 %} 3452 3453 operand vReg_V2() 3454 %{ 3455 constraint(ALLOC_IN_RC(v2_reg)); 3456 match(VecA); 3457 match(vReg); 3458 op_cost(0); 3459 format %{ %} 3460 interface(REG_INTER); 3461 %} 3462 3463 operand vReg_V3() 3464 %{ 3465 constraint(ALLOC_IN_RC(v3_reg)); 3466 match(VecA); 3467 match(vReg); 3468 op_cost(0); 3469 format %{ %} 3470 interface(REG_INTER); 3471 %} 3472 3473 operand vReg_V4() 3474 %{ 3475 constraint(ALLOC_IN_RC(v4_reg)); 3476 match(VecA); 3477 match(vReg); 3478 op_cost(0); 3479 format %{ %} 3480 interface(REG_INTER); 3481 %} 3482 3483 operand vReg_V5() 3484 %{ 3485 constraint(ALLOC_IN_RC(v5_reg)); 3486 match(VecA); 3487 match(vReg); 3488 op_cost(0); 3489 format %{ %} 3490 interface(REG_INTER); 3491 %} 3492 3493 operand vReg_V6() 3494 %{ 3495 constraint(ALLOC_IN_RC(v6_reg)); 3496 match(VecA); 3497 match(vReg); 3498 op_cost(0); 3499 format %{ %} 3500 interface(REG_INTER); 3501 %} 3502 3503 operand vReg_V7() 3504 %{ 3505 constraint(ALLOC_IN_RC(v7_reg)); 3506 match(VecA); 3507 match(vReg); 3508 op_cost(0); 3509 format %{ %} 3510 interface(REG_INTER); 3511 %} 3512 3513 operand vReg_V8() 3514 %{ 3515 constraint(ALLOC_IN_RC(v8_reg)); 3516 match(VecA); 3517 match(vReg); 3518 op_cost(0); 3519 format %{ %} 3520 interface(REG_INTER); 3521 %} 3522 3523 operand vReg_V9() 3524 %{ 3525 constraint(ALLOC_IN_RC(v9_reg)); 3526 match(VecA); 3527 match(vReg); 3528 op_cost(0); 3529 format %{ %} 3530 interface(REG_INTER); 3531 %} 3532 3533 operand vReg_V10() 3534 %{ 3535 constraint(ALLOC_IN_RC(v10_reg)); 3536 match(VecA); 3537 match(vReg); 3538 op_cost(0); 3539 format %{ %} 3540 interface(REG_INTER); 3541 %} 3542 3543 operand vReg_V11() 3544 %{ 3545 constraint(ALLOC_IN_RC(v11_reg)); 3546 match(VecA); 3547 match(vReg); 3548 op_cost(0); 3549 format %{ %} 3550 interface(REG_INTER); 3551 %} 3552 3553 operand vReg_V12() 3554 %{ 3555 constraint(ALLOC_IN_RC(v12_reg)); 3556 match(VecA); 3557 match(vReg); 3558 op_cost(0); 3559 format %{ %} 3560 interface(REG_INTER); 3561 %} 3562 3563 operand vReg_V13() 3564 %{ 3565 constraint(ALLOC_IN_RC(v13_reg)); 3566 match(VecA); 3567 match(vReg); 3568 op_cost(0); 3569 format %{ %} 3570 interface(REG_INTER); 3571 %} 3572 3573 operand vReg_V14() 3574 %{ 3575 constraint(ALLOC_IN_RC(v14_reg)); 3576 match(VecA); 3577 match(vReg); 3578 op_cost(0); 3579 format %{ %} 3580 interface(REG_INTER); 3581 %} 3582 3583 operand vReg_V15() 3584 %{ 3585 constraint(ALLOC_IN_RC(v15_reg)); 3586 match(VecA); 3587 match(vReg); 3588 op_cost(0); 3589 format %{ %} 3590 interface(REG_INTER); 3591 %} 3592 3593 operand vRegMask() 3594 %{ 3595 constraint(ALLOC_IN_RC(vmask_reg)); 3596 match(RegVectMask); 3597 match(vRegMask_V0); 3598 op_cost(0); 3599 format %{ %} 3600 interface(REG_INTER); 3601 %} 3602 3603 // The mask value used to control execution of a masked 3604 // vector instruction is always supplied by vector register v0. 3605 operand vRegMask_V0() 3606 %{ 3607 constraint(ALLOC_IN_RC(vmask_reg_v0)); 3608 match(RegVectMask); 3609 match(vRegMask); 3610 op_cost(0); 3611 format %{ %} 3612 interface(REG_INTER); 3613 %} 3614 3615 // Java Thread Register 3616 operand javaThread_RegP(iRegP reg) 3617 %{ 3618 constraint(ALLOC_IN_RC(java_thread_reg)); // java_thread_reg 3619 match(reg); 3620 op_cost(0); 3621 format %{ %} 3622 interface(REG_INTER); 3623 %} 3624 3625 //----------Memory Operands---------------------------------------------------- 3626 // RISCV has only base_plus_offset and literal address mode, so no need to use 3627 // index and scale. Here set index as 0xffffffff and scale as 0x0. 3628 operand indirect(iRegP reg) 3629 %{ 3630 constraint(ALLOC_IN_RC(ptr_reg)); 3631 match(reg); 3632 op_cost(0); 3633 format %{ "[$reg]" %} 3634 interface(MEMORY_INTER) %{ 3635 base($reg); 3636 index(0xffffffff); 3637 scale(0x0); 3638 disp(0x0); 3639 %} 3640 %} 3641 3642 operand indOffI(iRegP reg, immIOffset off) 3643 %{ 3644 constraint(ALLOC_IN_RC(ptr_reg)); 3645 match(AddP reg off); 3646 op_cost(0); 3647 format %{ "[$reg, $off]" %} 3648 interface(MEMORY_INTER) %{ 3649 base($reg); 3650 index(0xffffffff); 3651 scale(0x0); 3652 disp($off); 3653 %} 3654 %} 3655 3656 operand indOffL(iRegP reg, immLOffset off) 3657 %{ 3658 constraint(ALLOC_IN_RC(ptr_reg)); 3659 match(AddP reg off); 3660 op_cost(0); 3661 format %{ "[$reg, $off]" %} 3662 interface(MEMORY_INTER) %{ 3663 base($reg); 3664 index(0xffffffff); 3665 scale(0x0); 3666 disp($off); 3667 %} 3668 %} 3669 3670 operand indirectN(iRegN reg) 3671 %{ 3672 predicate(CompressedOops::shift() == 0); 3673 constraint(ALLOC_IN_RC(ptr_reg)); 3674 match(DecodeN reg); 3675 op_cost(0); 3676 format %{ "[$reg]\t# narrow" %} 3677 interface(MEMORY_INTER) %{ 3678 base($reg); 3679 index(0xffffffff); 3680 scale(0x0); 3681 disp(0x0); 3682 %} 3683 %} 3684 3685 operand indOffIN(iRegN reg, immIOffset off) 3686 %{ 3687 predicate(CompressedOops::shift() == 0); 3688 constraint(ALLOC_IN_RC(ptr_reg)); 3689 match(AddP (DecodeN reg) off); 3690 op_cost(0); 3691 format %{ "[$reg, $off]\t# narrow" %} 3692 interface(MEMORY_INTER) %{ 3693 base($reg); 3694 index(0xffffffff); 3695 scale(0x0); 3696 disp($off); 3697 %} 3698 %} 3699 3700 operand indOffLN(iRegN reg, immLOffset off) 3701 %{ 3702 predicate(CompressedOops::shift() == 0); 3703 constraint(ALLOC_IN_RC(ptr_reg)); 3704 match(AddP (DecodeN reg) off); 3705 op_cost(0); 3706 format %{ "[$reg, $off]\t# narrow" %} 3707 interface(MEMORY_INTER) %{ 3708 base($reg); 3709 index(0xffffffff); 3710 scale(0x0); 3711 disp($off); 3712 %} 3713 %} 3714 3715 //----------Special Memory Operands-------------------------------------------- 3716 // Stack Slot Operand - This operand is used for loading and storing temporary 3717 // values on the stack where a match requires a value to 3718 // flow through memory. 3719 operand stackSlotI(sRegI reg) 3720 %{ 3721 constraint(ALLOC_IN_RC(stack_slots)); 3722 // No match rule because this operand is only generated in matching 3723 // match(RegI); 3724 format %{ "[$reg]" %} 3725 interface(MEMORY_INTER) %{ 3726 base(0x02); // RSP 3727 index(0xffffffff); // No Index 3728 scale(0x0); // No Scale 3729 disp($reg); // Stack Offset 3730 %} 3731 %} 3732 3733 operand stackSlotF(sRegF reg) 3734 %{ 3735 constraint(ALLOC_IN_RC(stack_slots)); 3736 // No match rule because this operand is only generated in matching 3737 // match(RegF); 3738 format %{ "[$reg]" %} 3739 interface(MEMORY_INTER) %{ 3740 base(0x02); // RSP 3741 index(0xffffffff); // No Index 3742 scale(0x0); // No Scale 3743 disp($reg); // Stack Offset 3744 %} 3745 %} 3746 3747 operand stackSlotD(sRegD reg) 3748 %{ 3749 constraint(ALLOC_IN_RC(stack_slots)); 3750 // No match rule because this operand is only generated in matching 3751 // match(RegD); 3752 format %{ "[$reg]" %} 3753 interface(MEMORY_INTER) %{ 3754 base(0x02); // RSP 3755 index(0xffffffff); // No Index 3756 scale(0x0); // No Scale 3757 disp($reg); // Stack Offset 3758 %} 3759 %} 3760 3761 operand stackSlotL(sRegL reg) 3762 %{ 3763 constraint(ALLOC_IN_RC(stack_slots)); 3764 // No match rule because this operand is only generated in matching 3765 // match(RegL); 3766 format %{ "[$reg]" %} 3767 interface(MEMORY_INTER) %{ 3768 base(0x02); // RSP 3769 index(0xffffffff); // No Index 3770 scale(0x0); // No Scale 3771 disp($reg); // Stack Offset 3772 %} 3773 %} 3774 3775 // Special operand allowing long args to int ops to be truncated for free 3776 3777 operand iRegL2I(iRegL reg) %{ 3778 3779 op_cost(0); 3780 3781 match(ConvL2I reg); 3782 3783 format %{ "l2i($reg)" %} 3784 3785 interface(REG_INTER) 3786 %} 3787 3788 3789 // Comparison Operands 3790 // NOTE: Label is a predefined operand which should not be redefined in 3791 // the AD file. It is generically handled within the ADLC. 3792 3793 //----------Conditional Branch Operands---------------------------------------- 3794 // Comparison Op - This is the operation of the comparison, and is limited to 3795 // the following set of codes: 3796 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3797 // 3798 // Other attributes of the comparison, such as unsignedness, are specified 3799 // by the comparison instruction that sets a condition code flags register. 3800 // That result is represented by a flags operand whose subtype is appropriate 3801 // to the unsignedness (etc.) of the comparison. 3802 // 3803 // Later, the instruction which matches both the Comparison Op (a Bool) and 3804 // the flags (produced by the Cmp) specifies the coding of the comparison op 3805 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3806 3807 3808 // used for signed integral comparisons and fp comparisons 3809 operand cmpOp() 3810 %{ 3811 match(Bool); 3812 3813 format %{ "" %} 3814 3815 // the values in interface derives from struct BoolTest::mask 3816 interface(COND_INTER) %{ 3817 equal(0x0, "eq"); 3818 greater(0x1, "gt"); 3819 overflow(0x2, "overflow"); 3820 less(0x3, "lt"); 3821 not_equal(0x4, "ne"); 3822 less_equal(0x5, "le"); 3823 no_overflow(0x6, "no_overflow"); 3824 greater_equal(0x7, "ge"); 3825 %} 3826 %} 3827 3828 // used for unsigned integral comparisons 3829 operand cmpOpU() 3830 %{ 3831 match(Bool); 3832 3833 format %{ "" %} 3834 // the values in interface derives from struct BoolTest::mask 3835 interface(COND_INTER) %{ 3836 equal(0x0, "eq"); 3837 greater(0x1, "gtu"); 3838 overflow(0x2, "overflow"); 3839 less(0x3, "ltu"); 3840 not_equal(0x4, "ne"); 3841 less_equal(0x5, "leu"); 3842 no_overflow(0x6, "no_overflow"); 3843 greater_equal(0x7, "geu"); 3844 %} 3845 %} 3846 3847 // used for certain integral comparisons which can be 3848 // converted to bxx instructions 3849 operand cmpOpEqNe() 3850 %{ 3851 match(Bool); 3852 op_cost(0); 3853 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3854 n->as_Bool()->_test._test == BoolTest::eq); 3855 3856 format %{ "" %} 3857 interface(COND_INTER) %{ 3858 equal(0x0, "eq"); 3859 greater(0x1, "gt"); 3860 overflow(0x2, "overflow"); 3861 less(0x3, "lt"); 3862 not_equal(0x4, "ne"); 3863 less_equal(0x5, "le"); 3864 no_overflow(0x6, "no_overflow"); 3865 greater_equal(0x7, "ge"); 3866 %} 3867 %} 3868 3869 operand cmpOpULtGe() 3870 %{ 3871 match(Bool); 3872 op_cost(0); 3873 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3874 n->as_Bool()->_test._test == BoolTest::ge); 3875 3876 format %{ "" %} 3877 interface(COND_INTER) %{ 3878 equal(0x0, "eq"); 3879 greater(0x1, "gtu"); 3880 overflow(0x2, "overflow"); 3881 less(0x3, "ltu"); 3882 not_equal(0x4, "ne"); 3883 less_equal(0x5, "leu"); 3884 no_overflow(0x6, "no_overflow"); 3885 greater_equal(0x7, "geu"); 3886 %} 3887 %} 3888 3889 operand cmpOpUEqNeLeGt() 3890 %{ 3891 match(Bool); 3892 op_cost(0); 3893 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3894 n->as_Bool()->_test._test == BoolTest::eq || 3895 n->as_Bool()->_test._test == BoolTest::le || 3896 n->as_Bool()->_test._test == BoolTest::gt); 3897 3898 format %{ "" %} 3899 interface(COND_INTER) %{ 3900 equal(0x0, "eq"); 3901 greater(0x1, "gtu"); 3902 overflow(0x2, "overflow"); 3903 less(0x3, "ltu"); 3904 not_equal(0x4, "ne"); 3905 less_equal(0x5, "leu"); 3906 no_overflow(0x6, "no_overflow"); 3907 greater_equal(0x7, "geu"); 3908 %} 3909 %} 3910 3911 3912 // Flags register, used as output of compare logic 3913 operand rFlagsReg() 3914 %{ 3915 constraint(ALLOC_IN_RC(reg_flags)); 3916 match(RegFlags); 3917 3918 op_cost(0); 3919 format %{ "RFLAGS" %} 3920 interface(REG_INTER); 3921 %} 3922 3923 // Special Registers 3924 3925 // Method Register 3926 operand inline_cache_RegP(iRegP reg) 3927 %{ 3928 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 3929 match(reg); 3930 match(iRegPNoSp); 3931 op_cost(0); 3932 format %{ %} 3933 interface(REG_INTER); 3934 %} 3935 3936 //----------OPERAND CLASSES---------------------------------------------------- 3937 // Operand Classes are groups of operands that are used as to simplify 3938 // instruction definitions by not requiring the AD writer to specify 3939 // separate instructions for every form of operand when the 3940 // instruction accepts multiple operand types with the same basic 3941 // encoding and format. The classic case of this is memory operands. 3942 3943 // memory is used to define read/write location for load/store 3944 // instruction defs. we can turn a memory op into an Address 3945 3946 opclass memory(indirect, indOffI, indOffL, indirectN, indOffIN, indOffLN); 3947 3948 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 3949 // operations. it allows the src to be either an iRegI or a (ConvL2I 3950 // iRegL). in the latter case the l2i normally planted for a ConvL2I 3951 // can be elided because the 32-bit instruction will just employ the 3952 // lower 32 bits anyway. 3953 // 3954 // n.b. this does not elide all L2I conversions. if the truncated 3955 // value is consumed by more than one operation then the ConvL2I 3956 // cannot be bundled into the consuming nodes so an l2i gets planted 3957 // (actually an addiw $dst, $src, 0) and the downstream instructions 3958 // consume the result of the L2I as an iRegI input. That's a shame since 3959 // the addiw is actually redundant but its not too costly. 3960 3961 opclass iRegIorL2I(iRegI, iRegL2I); 3962 opclass iRegIorL(iRegI, iRegL); 3963 opclass iRegNorP(iRegN, iRegP); 3964 opclass iRegILNP(iRegI, iRegL, iRegN, iRegP); 3965 opclass iRegILNPNoSp(iRegINoSp, iRegLNoSp, iRegNNoSp, iRegPNoSp); 3966 opclass immIorL(immI, immL); 3967 3968 //----------PIPELINE----------------------------------------------------------- 3969 // Rules which define the behavior of the target architectures pipeline. 3970 3971 // For specific pipelines, e.g. generic RISC-V, define the stages of that pipeline 3972 //pipe_desc(ID, EX, MEM, WR); 3973 #define ID S0 3974 #define EX S1 3975 #define MEM S2 3976 #define WR S3 3977 3978 // Integer ALU reg operation 3979 pipeline %{ 3980 3981 attributes %{ 3982 // RISC-V instructions are of fixed length 3983 fixed_size_instructions; // Fixed size instructions TODO does 3984 max_instructions_per_bundle = 2; // Generic RISC-V 1, Sifive Series 7 2 3985 // RISC-V instructions come in 32-bit word units 3986 instruction_unit_size = 4; // An instruction is 4 bytes long 3987 instruction_fetch_unit_size = 64; // The processor fetches one line 3988 instruction_fetch_units = 1; // of 64 bytes 3989 3990 // List of nop instructions 3991 nops( MachNop ); 3992 %} 3993 3994 // We don't use an actual pipeline model so don't care about resources 3995 // or description. we do use pipeline classes to introduce fixed 3996 // latencies 3997 3998 //----------RESOURCES---------------------------------------------------------- 3999 // Resources are the functional units available to the machine 4000 4001 // Generic RISC-V pipeline 4002 // 1 decoder 4003 // 1 instruction decoded per cycle 4004 // 1 load/store ops per cycle, 1 branch, 1 FPU 4005 // 1 mul, 1 div 4006 4007 resources ( DECODE, 4008 ALU, 4009 MUL, 4010 DIV, 4011 BRANCH, 4012 LDST, 4013 FPU); 4014 4015 //----------PIPELINE DESCRIPTION----------------------------------------------- 4016 // Pipeline Description specifies the stages in the machine's pipeline 4017 4018 // Define the pipeline as a generic 6 stage pipeline 4019 pipe_desc(S0, S1, S2, S3, S4, S5); 4020 4021 //----------PIPELINE CLASSES--------------------------------------------------- 4022 // Pipeline Classes describe the stages in which input and output are 4023 // referenced by the hardware pipeline. 4024 4025 pipe_class fp_dop_reg_reg_s(fRegF dst, fRegF src1, fRegF src2) 4026 %{ 4027 single_instruction; 4028 src1 : S1(read); 4029 src2 : S2(read); 4030 dst : S5(write); 4031 DECODE : ID; 4032 FPU : S5; 4033 %} 4034 4035 pipe_class fp_dop_reg_reg_d(fRegD dst, fRegD src1, fRegD src2) 4036 %{ 4037 src1 : S1(read); 4038 src2 : S2(read); 4039 dst : S5(write); 4040 DECODE : ID; 4041 FPU : S5; 4042 %} 4043 4044 pipe_class fp_uop_s(fRegF dst, fRegF src) 4045 %{ 4046 single_instruction; 4047 src : S1(read); 4048 dst : S5(write); 4049 DECODE : ID; 4050 FPU : S5; 4051 %} 4052 4053 pipe_class fp_uop_d(fRegD dst, fRegD src) 4054 %{ 4055 single_instruction; 4056 src : S1(read); 4057 dst : S5(write); 4058 DECODE : ID; 4059 FPU : S5; 4060 %} 4061 4062 pipe_class fp_d2f(fRegF dst, fRegD src) 4063 %{ 4064 single_instruction; 4065 src : S1(read); 4066 dst : S5(write); 4067 DECODE : ID; 4068 FPU : S5; 4069 %} 4070 4071 pipe_class fp_f2d(fRegD dst, fRegF src) 4072 %{ 4073 single_instruction; 4074 src : S1(read); 4075 dst : S5(write); 4076 DECODE : ID; 4077 FPU : S5; 4078 %} 4079 4080 pipe_class fp_f2i(iRegINoSp dst, fRegF src) 4081 %{ 4082 single_instruction; 4083 src : S1(read); 4084 dst : S5(write); 4085 DECODE : ID; 4086 FPU : S5; 4087 %} 4088 4089 pipe_class fp_f2l(iRegLNoSp dst, fRegF src) 4090 %{ 4091 single_instruction; 4092 src : S1(read); 4093 dst : S5(write); 4094 DECODE : ID; 4095 FPU : S5; 4096 %} 4097 4098 pipe_class fp_i2f(fRegF dst, iRegIorL2I src) 4099 %{ 4100 single_instruction; 4101 src : S1(read); 4102 dst : S5(write); 4103 DECODE : ID; 4104 FPU : S5; 4105 %} 4106 4107 pipe_class fp_l2f(fRegF dst, iRegL src) 4108 %{ 4109 single_instruction; 4110 src : S1(read); 4111 dst : S5(write); 4112 DECODE : ID; 4113 FPU : S5; 4114 %} 4115 4116 pipe_class fp_d2i(iRegINoSp dst, fRegD src) 4117 %{ 4118 single_instruction; 4119 src : S1(read); 4120 dst : S5(write); 4121 DECODE : ID; 4122 FPU : S5; 4123 %} 4124 4125 pipe_class fp_d2l(iRegLNoSp dst, fRegD src) 4126 %{ 4127 single_instruction; 4128 src : S1(read); 4129 dst : S5(write); 4130 DECODE : ID; 4131 FPU : S5; 4132 %} 4133 4134 pipe_class fp_i2d(fRegD dst, iRegIorL2I src) 4135 %{ 4136 single_instruction; 4137 src : S1(read); 4138 dst : S5(write); 4139 DECODE : ID; 4140 FPU : S5; 4141 %} 4142 4143 pipe_class fp_l2d(fRegD dst, iRegIorL2I src) 4144 %{ 4145 single_instruction; 4146 src : S1(read); 4147 dst : S5(write); 4148 DECODE : ID; 4149 FPU : S5; 4150 %} 4151 4152 pipe_class fp_div_s(fRegF dst, fRegF src1, fRegF src2) 4153 %{ 4154 single_instruction; 4155 src1 : S1(read); 4156 src2 : S2(read); 4157 dst : S5(write); 4158 DECODE : ID; 4159 FPU : S5; 4160 %} 4161 4162 pipe_class fp_div_d(fRegD dst, fRegD src1, fRegD src2) 4163 %{ 4164 single_instruction; 4165 src1 : S1(read); 4166 src2 : S2(read); 4167 dst : S5(write); 4168 DECODE : ID; 4169 FPU : S5; 4170 %} 4171 4172 pipe_class fp_sqrt_s(fRegF dst, fRegF src1, fRegF src2) 4173 %{ 4174 single_instruction; 4175 src1 : S1(read); 4176 src2 : S2(read); 4177 dst : S5(write); 4178 DECODE : ID; 4179 FPU : S5; 4180 %} 4181 4182 pipe_class fp_sqrt_d(fRegD dst, fRegD src1, fRegD src2) 4183 %{ 4184 single_instruction; 4185 src1 : S1(read); 4186 src2 : S2(read); 4187 dst : S5(write); 4188 DECODE : ID; 4189 FPU : S5; 4190 %} 4191 4192 pipe_class fp_load_constant_s(fRegF dst) 4193 %{ 4194 single_instruction; 4195 dst : S5(write); 4196 DECODE : ID; 4197 FPU : S5; 4198 %} 4199 4200 pipe_class fp_load_constant_d(fRegD dst) 4201 %{ 4202 single_instruction; 4203 dst : S5(write); 4204 DECODE : ID; 4205 FPU : S5; 4206 %} 4207 4208 pipe_class fp_load_mem_s(fRegF dst, memory mem) 4209 %{ 4210 single_instruction; 4211 mem : S1(read); 4212 dst : S5(write); 4213 DECODE : ID; 4214 LDST : MEM; 4215 %} 4216 4217 pipe_class fp_load_mem_d(fRegD dst, memory mem) 4218 %{ 4219 single_instruction; 4220 mem : S1(read); 4221 dst : S5(write); 4222 DECODE : ID; 4223 LDST : MEM; 4224 %} 4225 4226 pipe_class fp_store_reg_s(fRegF src, memory mem) 4227 %{ 4228 single_instruction; 4229 src : S1(read); 4230 mem : S5(write); 4231 DECODE : ID; 4232 LDST : MEM; 4233 %} 4234 4235 pipe_class fp_store_reg_d(fRegD src, memory mem) 4236 %{ 4237 single_instruction; 4238 src : S1(read); 4239 mem : S5(write); 4240 DECODE : ID; 4241 LDST : MEM; 4242 %} 4243 4244 //------- Integer ALU operations -------------------------- 4245 4246 // Integer ALU reg-reg operation 4247 // Operands needs in ID, result generated in EX 4248 // E.g. ADD Rd, Rs1, Rs2 4249 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4250 %{ 4251 single_instruction; 4252 dst : EX(write); 4253 src1 : ID(read); 4254 src2 : ID(read); 4255 DECODE : ID; 4256 ALU : EX; 4257 %} 4258 4259 // Integer ALU reg operation with constant shift 4260 // E.g. SLLI Rd, Rs1, #shift 4261 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 4262 %{ 4263 single_instruction; 4264 dst : EX(write); 4265 src1 : ID(read); 4266 DECODE : ID; 4267 ALU : EX; 4268 %} 4269 4270 // Integer ALU reg-reg operation with variable shift 4271 // both operands must be available in ID 4272 // E.g. SLL Rd, Rs1, Rs2 4273 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 4274 %{ 4275 single_instruction; 4276 dst : EX(write); 4277 src1 : ID(read); 4278 src2 : ID(read); 4279 DECODE : ID; 4280 ALU : EX; 4281 %} 4282 4283 // Integer ALU reg operation 4284 // E.g. NEG Rd, Rs2 4285 pipe_class ialu_reg(iRegI dst, iRegI src) 4286 %{ 4287 single_instruction; 4288 dst : EX(write); 4289 src : ID(read); 4290 DECODE : ID; 4291 ALU : EX; 4292 %} 4293 4294 // Integer ALU reg immediate operation 4295 // E.g. ADDI Rd, Rs1, #imm 4296 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 4297 %{ 4298 single_instruction; 4299 dst : EX(write); 4300 src1 : ID(read); 4301 DECODE : ID; 4302 ALU : EX; 4303 %} 4304 4305 // Integer ALU immediate operation (no source operands) 4306 // E.g. LI Rd, #imm 4307 pipe_class ialu_imm(iRegI dst) 4308 %{ 4309 single_instruction; 4310 dst : EX(write); 4311 DECODE : ID; 4312 ALU : EX; 4313 %} 4314 4315 //------- Multiply pipeline operations -------------------- 4316 4317 // Multiply reg-reg 4318 // E.g. MULW Rd, Rs1, Rs2 4319 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4320 %{ 4321 single_instruction; 4322 dst : WR(write); 4323 src1 : ID(read); 4324 src2 : ID(read); 4325 DECODE : ID; 4326 MUL : WR; 4327 %} 4328 4329 // E.g. MUL RD, Rs1, Rs2 4330 pipe_class lmul_reg_reg(iRegL dst, iRegL src1, iRegL src2) 4331 %{ 4332 single_instruction; 4333 fixed_latency(3); // Maximum latency for 64 bit mul 4334 dst : WR(write); 4335 src1 : ID(read); 4336 src2 : ID(read); 4337 DECODE : ID; 4338 MUL : WR; 4339 %} 4340 4341 //------- Divide pipeline operations -------------------- 4342 4343 // E.g. DIVW Rd, Rs1, Rs2 4344 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4345 %{ 4346 single_instruction; 4347 fixed_latency(8); // Maximum latency for 32 bit divide 4348 dst : WR(write); 4349 src1 : ID(read); 4350 src2 : ID(read); 4351 DECODE : ID; 4352 DIV : WR; 4353 %} 4354 4355 // E.g. DIV RD, Rs1, Rs2 4356 pipe_class ldiv_reg_reg(iRegL dst, iRegL src1, iRegL src2) 4357 %{ 4358 single_instruction; 4359 fixed_latency(16); // Maximum latency for 64 bit divide 4360 dst : WR(write); 4361 src1 : ID(read); 4362 src2 : ID(read); 4363 DECODE : ID; 4364 DIV : WR; 4365 %} 4366 4367 //------- Load pipeline operations ------------------------ 4368 4369 // Load - prefetch 4370 // Eg. PREFETCH_W mem 4371 pipe_class iload_prefetch(memory mem) 4372 %{ 4373 single_instruction; 4374 mem : ID(read); 4375 DECODE : ID; 4376 LDST : MEM; 4377 %} 4378 4379 // Load - reg, mem 4380 // E.g. LA Rd, mem 4381 pipe_class iload_reg_mem(iRegI dst, memory mem) 4382 %{ 4383 single_instruction; 4384 dst : WR(write); 4385 mem : ID(read); 4386 DECODE : ID; 4387 LDST : MEM; 4388 %} 4389 4390 // Load - reg, reg 4391 // E.g. LD Rd, Rs 4392 pipe_class iload_reg_reg(iRegI dst, iRegI src) 4393 %{ 4394 single_instruction; 4395 dst : WR(write); 4396 src : ID(read); 4397 DECODE : ID; 4398 LDST : MEM; 4399 %} 4400 4401 //------- Store pipeline operations ----------------------- 4402 4403 // Store - zr, mem 4404 // E.g. SD zr, mem 4405 pipe_class istore_mem(memory mem) 4406 %{ 4407 single_instruction; 4408 mem : ID(read); 4409 DECODE : ID; 4410 LDST : MEM; 4411 %} 4412 4413 // Store - reg, mem 4414 // E.g. SD Rs, mem 4415 pipe_class istore_reg_mem(iRegI src, memory mem) 4416 %{ 4417 single_instruction; 4418 mem : ID(read); 4419 src : EX(read); 4420 DECODE : ID; 4421 LDST : MEM; 4422 %} 4423 4424 // Store - reg, reg 4425 // E.g. SD Rs2, Rs1 4426 pipe_class istore_reg_reg(iRegI dst, iRegI src) 4427 %{ 4428 single_instruction; 4429 dst : ID(read); 4430 src : EX(read); 4431 DECODE : ID; 4432 LDST : MEM; 4433 %} 4434 4435 //------- Control transfer pipeline operations ------------ 4436 4437 // Branch 4438 pipe_class pipe_branch() 4439 %{ 4440 single_instruction; 4441 DECODE : ID; 4442 BRANCH : EX; 4443 %} 4444 4445 // Branch 4446 pipe_class pipe_branch_reg(iRegI src) 4447 %{ 4448 single_instruction; 4449 src : ID(read); 4450 DECODE : ID; 4451 BRANCH : EX; 4452 %} 4453 4454 // Compare & Branch 4455 // E.g. BEQ Rs1, Rs2, L 4456 pipe_class pipe_cmp_branch(iRegI src1, iRegI src2) 4457 %{ 4458 single_instruction; 4459 src1 : ID(read); 4460 src2 : ID(read); 4461 DECODE : ID; 4462 BRANCH : EX; 4463 %} 4464 4465 // E.g. BEQZ Rs, L 4466 pipe_class pipe_cmpz_branch(iRegI src) 4467 %{ 4468 single_instruction; 4469 src : ID(read); 4470 DECODE : ID; 4471 BRANCH : EX; 4472 %} 4473 4474 //------- Synchronisation operations ---------------------- 4475 // Any operation requiring serialization 4476 // E.g. FENCE/Atomic Ops/Load Acquire/Store Release 4477 pipe_class pipe_serial() 4478 %{ 4479 single_instruction; 4480 force_serialization; 4481 fixed_latency(16); 4482 DECODE : ID; 4483 LDST : MEM; 4484 %} 4485 4486 pipe_class pipe_slow() 4487 %{ 4488 instruction_count(10); 4489 multiple_bundles; 4490 force_serialization; 4491 fixed_latency(16); 4492 DECODE : ID; 4493 LDST : MEM; 4494 %} 4495 4496 // Empty pipeline class 4497 pipe_class pipe_class_empty() 4498 %{ 4499 single_instruction; 4500 fixed_latency(0); 4501 %} 4502 4503 // Default pipeline class. 4504 pipe_class pipe_class_default() 4505 %{ 4506 single_instruction; 4507 fixed_latency(2); 4508 %} 4509 4510 // Pipeline class for compares. 4511 pipe_class pipe_class_compare() 4512 %{ 4513 single_instruction; 4514 fixed_latency(16); 4515 %} 4516 4517 // Pipeline class for memory operations. 4518 pipe_class pipe_class_memory() 4519 %{ 4520 single_instruction; 4521 fixed_latency(16); 4522 %} 4523 4524 // Pipeline class for call. 4525 pipe_class pipe_class_call() 4526 %{ 4527 single_instruction; 4528 fixed_latency(100); 4529 %} 4530 4531 // Define the class for the Nop node. 4532 define %{ 4533 MachNop = pipe_class_empty; 4534 %} 4535 %} 4536 //----------INSTRUCTIONS------------------------------------------------------- 4537 // 4538 // match -- States which machine-independent subtree may be replaced 4539 // by this instruction. 4540 // ins_cost -- The estimated cost of this instruction is used by instruction 4541 // selection to identify a minimum cost tree of machine 4542 // instructions that matches a tree of machine-independent 4543 // instructions. 4544 // format -- A string providing the disassembly for this instruction. 4545 // The value of an instruction's operand may be inserted 4546 // by referring to it with a '$' prefix. 4547 // opcode -- Three instruction opcodes may be provided. These are referred 4548 // to within an encode class as $primary, $secondary, and $tertiary 4549 // rrspectively. The primary opcode is commonly used to 4550 // indicate the type of machine instruction, while secondary 4551 // and tertiary are often used for prefix options or addressing 4552 // modes. 4553 // ins_encode -- A list of encode classes with parameters. The encode class 4554 // name must have been defined in an 'enc_class' specification 4555 // in the encode section of the architecture description. 4556 4557 // ============================================================================ 4558 // Memory (Load/Store) Instructions 4559 4560 // Load Instructions 4561 4562 // Load Byte (8 bit signed) 4563 instruct loadB(iRegINoSp dst, memory mem) 4564 %{ 4565 match(Set dst (LoadB mem)); 4566 4567 ins_cost(LOAD_COST); 4568 format %{ "lb $dst, $mem\t# byte, #@loadB" %} 4569 4570 ins_encode %{ 4571 __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4572 %} 4573 4574 ins_pipe(iload_reg_mem); 4575 %} 4576 4577 // Load Byte (8 bit signed) into long 4578 instruct loadB2L(iRegLNoSp dst, memory mem) 4579 %{ 4580 match(Set dst (ConvI2L (LoadB mem))); 4581 4582 ins_cost(LOAD_COST); 4583 format %{ "lb $dst, $mem\t# byte, #@loadB2L" %} 4584 4585 ins_encode %{ 4586 __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4587 %} 4588 4589 ins_pipe(iload_reg_mem); 4590 %} 4591 4592 // Load Byte (8 bit unsigned) 4593 instruct loadUB(iRegINoSp dst, memory mem) 4594 %{ 4595 match(Set dst (LoadUB mem)); 4596 4597 ins_cost(LOAD_COST); 4598 format %{ "lbu $dst, $mem\t# byte, #@loadUB" %} 4599 4600 ins_encode %{ 4601 __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4602 %} 4603 4604 ins_pipe(iload_reg_mem); 4605 %} 4606 4607 // Load Byte (8 bit unsigned) into long 4608 instruct loadUB2L(iRegLNoSp dst, memory mem) 4609 %{ 4610 match(Set dst (ConvI2L (LoadUB mem))); 4611 4612 ins_cost(LOAD_COST); 4613 format %{ "lbu $dst, $mem\t# byte, #@loadUB2L" %} 4614 4615 ins_encode %{ 4616 __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4617 %} 4618 4619 ins_pipe(iload_reg_mem); 4620 %} 4621 4622 // Load Short (16 bit signed) 4623 instruct loadS(iRegINoSp dst, memory mem) 4624 %{ 4625 match(Set dst (LoadS mem)); 4626 4627 ins_cost(LOAD_COST); 4628 format %{ "lh $dst, $mem\t# short, #@loadS" %} 4629 4630 ins_encode %{ 4631 __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4632 %} 4633 4634 ins_pipe(iload_reg_mem); 4635 %} 4636 4637 // Load Short (16 bit signed) into long 4638 instruct loadS2L(iRegLNoSp dst, memory mem) 4639 %{ 4640 match(Set dst (ConvI2L (LoadS mem))); 4641 4642 ins_cost(LOAD_COST); 4643 format %{ "lh $dst, $mem\t# short, #@loadS2L" %} 4644 4645 ins_encode %{ 4646 __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4647 %} 4648 4649 ins_pipe(iload_reg_mem); 4650 %} 4651 4652 // Load Char (16 bit unsigned) 4653 instruct loadUS(iRegINoSp dst, memory mem) 4654 %{ 4655 match(Set dst (LoadUS mem)); 4656 4657 ins_cost(LOAD_COST); 4658 format %{ "lhu $dst, $mem\t# short, #@loadUS" %} 4659 4660 ins_encode %{ 4661 __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4662 %} 4663 4664 ins_pipe(iload_reg_mem); 4665 %} 4666 4667 // Load Short/Char (16 bit unsigned) into long 4668 instruct loadUS2L(iRegLNoSp dst, memory mem) 4669 %{ 4670 match(Set dst (ConvI2L (LoadUS mem))); 4671 4672 ins_cost(LOAD_COST); 4673 format %{ "lhu $dst, $mem\t# short, #@loadUS2L" %} 4674 4675 ins_encode %{ 4676 __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4677 %} 4678 4679 ins_pipe(iload_reg_mem); 4680 %} 4681 4682 // Load Integer (32 bit signed) 4683 instruct loadI(iRegINoSp dst, memory mem) 4684 %{ 4685 match(Set dst (LoadI mem)); 4686 4687 ins_cost(LOAD_COST); 4688 format %{ "lw $dst, $mem\t# int, #@loadI" %} 4689 4690 ins_encode %{ 4691 __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4692 %} 4693 4694 ins_pipe(iload_reg_mem); 4695 %} 4696 4697 // Load Integer (32 bit signed) into long 4698 instruct loadI2L(iRegLNoSp dst, memory mem) 4699 %{ 4700 match(Set dst (ConvI2L (LoadI mem))); 4701 4702 ins_cost(LOAD_COST); 4703 format %{ "lw $dst, $mem\t# int, #@loadI2L" %} 4704 4705 ins_encode %{ 4706 __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4707 %} 4708 4709 ins_pipe(iload_reg_mem); 4710 %} 4711 4712 // Load Integer (32 bit unsigned) into long 4713 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 4714 %{ 4715 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4716 4717 ins_cost(LOAD_COST); 4718 format %{ "lwu $dst, $mem\t# int, #@loadUI2L" %} 4719 4720 ins_encode %{ 4721 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4722 %} 4723 4724 ins_pipe(iload_reg_mem); 4725 %} 4726 4727 // Load Long (64 bit signed) 4728 instruct loadL(iRegLNoSp dst, memory mem) 4729 %{ 4730 match(Set dst (LoadL mem)); 4731 4732 ins_cost(LOAD_COST); 4733 format %{ "ld $dst, $mem\t# int, #@loadL" %} 4734 4735 ins_encode %{ 4736 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4737 %} 4738 4739 ins_pipe(iload_reg_mem); 4740 %} 4741 4742 // Load Range 4743 instruct loadRange(iRegINoSp dst, memory mem) 4744 %{ 4745 match(Set dst (LoadRange mem)); 4746 4747 ins_cost(LOAD_COST); 4748 format %{ "lwu $dst, $mem\t# range, #@loadRange" %} 4749 4750 ins_encode %{ 4751 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4752 %} 4753 4754 ins_pipe(iload_reg_mem); 4755 %} 4756 4757 // Load Pointer 4758 instruct loadP(iRegPNoSp dst, memory mem) 4759 %{ 4760 match(Set dst (LoadP mem)); 4761 predicate(n->as_Load()->barrier_data() == 0); 4762 4763 ins_cost(LOAD_COST); 4764 format %{ "ld $dst, $mem\t# ptr, #@loadP" %} 4765 4766 ins_encode %{ 4767 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4768 %} 4769 4770 ins_pipe(iload_reg_mem); 4771 %} 4772 4773 // Load Compressed Pointer 4774 instruct loadN(iRegNNoSp dst, memory mem) 4775 %{ 4776 match(Set dst (LoadN mem)); 4777 4778 ins_cost(LOAD_COST); 4779 format %{ "lwu $dst, $mem\t# loadN, compressed ptr, #@loadN" %} 4780 4781 ins_encode %{ 4782 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4783 %} 4784 4785 ins_pipe(iload_reg_mem); 4786 %} 4787 4788 // Load Klass Pointer 4789 instruct loadKlass(iRegPNoSp dst, memory mem) 4790 %{ 4791 match(Set dst (LoadKlass mem)); 4792 4793 ins_cost(LOAD_COST); 4794 format %{ "ld $dst, $mem\t# class, #@loadKlass" %} 4795 4796 ins_encode %{ 4797 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4798 %} 4799 4800 ins_pipe(iload_reg_mem); 4801 %} 4802 4803 // Load Narrow Klass Pointer 4804 instruct loadNKlass(iRegNNoSp dst, memory mem) 4805 %{ 4806 match(Set dst (LoadNKlass mem)); 4807 4808 ins_cost(LOAD_COST); 4809 format %{ "lwu $dst, $mem\t# loadNKlass, compressed class ptr, #@loadNKlass" %} 4810 4811 ins_encode %{ 4812 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4813 %} 4814 4815 ins_pipe(iload_reg_mem); 4816 %} 4817 4818 // Load Float 4819 instruct loadF(fRegF dst, memory mem) 4820 %{ 4821 match(Set dst (LoadF mem)); 4822 4823 ins_cost(LOAD_COST); 4824 format %{ "flw $dst, $mem\t# float, #@loadF" %} 4825 4826 ins_encode %{ 4827 __ flw(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4828 %} 4829 4830 ins_pipe(fp_load_mem_s); 4831 %} 4832 4833 // Load Double 4834 instruct loadD(fRegD dst, memory mem) 4835 %{ 4836 match(Set dst (LoadD mem)); 4837 4838 ins_cost(LOAD_COST); 4839 format %{ "fld $dst, $mem\t# double, #@loadD" %} 4840 4841 ins_encode %{ 4842 __ fld(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4843 %} 4844 4845 ins_pipe(fp_load_mem_d); 4846 %} 4847 4848 // Load Int Constant 4849 instruct loadConI(iRegINoSp dst, immI src) 4850 %{ 4851 match(Set dst src); 4852 4853 ins_cost(ALU_COST); 4854 format %{ "mv $dst, $src\t# int, #@loadConI" %} 4855 4856 ins_encode(riscv_enc_mov_imm(dst, src)); 4857 4858 ins_pipe(ialu_imm); 4859 %} 4860 4861 // Load Long Constant 4862 instruct loadConL(iRegLNoSp dst, immL src) 4863 %{ 4864 match(Set dst src); 4865 4866 ins_cost(ALU_COST); 4867 format %{ "mv $dst, $src\t# long, #@loadConL" %} 4868 4869 ins_encode(riscv_enc_mov_imm(dst, src)); 4870 4871 ins_pipe(ialu_imm); 4872 %} 4873 4874 // Load Pointer Constant 4875 instruct loadConP(iRegPNoSp dst, immP con) 4876 %{ 4877 match(Set dst con); 4878 4879 ins_cost(ALU_COST); 4880 format %{ "mv $dst, $con\t# ptr, #@loadConP" %} 4881 4882 ins_encode(riscv_enc_mov_p(dst, con)); 4883 4884 ins_pipe(ialu_imm); 4885 %} 4886 4887 // Load Null Pointer Constant 4888 instruct loadConP0(iRegPNoSp dst, immP0 con) 4889 %{ 4890 match(Set dst con); 4891 4892 ins_cost(ALU_COST); 4893 format %{ "mv $dst, $con\t# null pointer, #@loadConP0" %} 4894 4895 ins_encode(riscv_enc_mov_zero(dst)); 4896 4897 ins_pipe(ialu_imm); 4898 %} 4899 4900 // Load Pointer Constant One 4901 instruct loadConP1(iRegPNoSp dst, immP_1 con) 4902 %{ 4903 match(Set dst con); 4904 4905 ins_cost(ALU_COST); 4906 format %{ "mv $dst, $con\t# load ptr constant one, #@loadConP1" %} 4907 4908 ins_encode(riscv_enc_mov_p1(dst)); 4909 4910 ins_pipe(ialu_imm); 4911 %} 4912 4913 // Load Byte Map Base Constant 4914 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 4915 %{ 4916 match(Set dst con); 4917 ins_cost(ALU_COST); 4918 format %{ "mv $dst, $con\t# Byte Map Base, #@loadByteMapBase" %} 4919 4920 ins_encode(riscv_enc_mov_byte_map_base(dst)); 4921 4922 ins_pipe(ialu_imm); 4923 %} 4924 4925 // Load Narrow Pointer Constant 4926 instruct loadConN(iRegNNoSp dst, immN con) 4927 %{ 4928 match(Set dst con); 4929 4930 ins_cost(ALU_COST * 4); 4931 format %{ "mv $dst, $con\t# compressed ptr, #@loadConN" %} 4932 4933 ins_encode(riscv_enc_mov_n(dst, con)); 4934 4935 ins_pipe(ialu_imm); 4936 %} 4937 4938 // Load Narrow Null Pointer Constant 4939 instruct loadConN0(iRegNNoSp dst, immN0 con) 4940 %{ 4941 match(Set dst con); 4942 4943 ins_cost(ALU_COST); 4944 format %{ "mv $dst, $con\t# compressed null pointer, #@loadConN0" %} 4945 4946 ins_encode(riscv_enc_mov_zero(dst)); 4947 4948 ins_pipe(ialu_imm); 4949 %} 4950 4951 // Load Narrow Klass Constant 4952 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 4953 %{ 4954 match(Set dst con); 4955 4956 ins_cost(ALU_COST * 6); 4957 format %{ "mv $dst, $con\t# compressed klass ptr, #@loadConNKlass" %} 4958 4959 ins_encode(riscv_enc_mov_nk(dst, con)); 4960 4961 ins_pipe(ialu_imm); 4962 %} 4963 4964 // Load Float Constant 4965 instruct loadConF(fRegF dst, immF con) %{ 4966 match(Set dst con); 4967 4968 ins_cost(LOAD_COST); 4969 format %{ 4970 "flw $dst, [$constantaddress]\t# load from constant table: float=$con, #@loadConF" 4971 %} 4972 4973 ins_encode %{ 4974 __ flw(as_FloatRegister($dst$$reg), $constantaddress($con)); 4975 %} 4976 4977 ins_pipe(fp_load_constant_s); 4978 %} 4979 4980 instruct loadConF0(fRegF dst, immF0 con) %{ 4981 match(Set dst con); 4982 4983 ins_cost(XFER_COST); 4984 4985 format %{ "fmv.w.x $dst, zr\t# float, #@loadConF0" %} 4986 4987 ins_encode %{ 4988 __ fmv_w_x(as_FloatRegister($dst$$reg), zr); 4989 %} 4990 4991 ins_pipe(fp_load_constant_s); 4992 %} 4993 4994 // Load Double Constant 4995 instruct loadConD(fRegD dst, immD con) %{ 4996 match(Set dst con); 4997 4998 ins_cost(LOAD_COST); 4999 format %{ 5000 "fld $dst, [$constantaddress]\t# load from constant table: double=$con, #@loadConD" 5001 %} 5002 5003 ins_encode %{ 5004 __ fld(as_FloatRegister($dst$$reg), $constantaddress($con)); 5005 %} 5006 5007 ins_pipe(fp_load_constant_d); 5008 %} 5009 5010 instruct loadConD0(fRegD dst, immD0 con) %{ 5011 match(Set dst con); 5012 5013 ins_cost(XFER_COST); 5014 5015 format %{ "fmv.d.x $dst, zr\t# double, #@loadConD0" %} 5016 5017 ins_encode %{ 5018 __ fmv_d_x(as_FloatRegister($dst$$reg), zr); 5019 %} 5020 5021 ins_pipe(fp_load_constant_d); 5022 %} 5023 5024 // Store Instructions 5025 // Store CMS card-mark Immediate 5026 instruct storeimmCM0(immI0 zero, memory mem) 5027 %{ 5028 match(Set mem (StoreCM mem zero)); 5029 5030 ins_cost(STORE_COST); 5031 format %{ "storestore (elided)\n\t" 5032 "sb zr, $mem\t# byte, #@storeimmCM0" %} 5033 5034 ins_encode %{ 5035 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 5036 %} 5037 5038 ins_pipe(istore_mem); 5039 %} 5040 5041 // Store CMS card-mark Immediate with intervening StoreStore 5042 // needed when using CMS with no conditional card marking 5043 instruct storeimmCM0_ordered(immI0 zero, memory mem) 5044 %{ 5045 match(Set mem (StoreCM mem zero)); 5046 5047 ins_cost(ALU_COST + STORE_COST); 5048 format %{ "membar(StoreStore)\n\t" 5049 "sb zr, $mem\t# byte, #@storeimmCM0_ordered" %} 5050 5051 ins_encode %{ 5052 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 5053 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 5054 %} 5055 5056 ins_pipe(istore_mem); 5057 %} 5058 5059 // Store Byte 5060 instruct storeB(iRegIorL2I src, memory mem) 5061 %{ 5062 match(Set mem (StoreB mem src)); 5063 5064 ins_cost(STORE_COST); 5065 format %{ "sb $src, $mem\t# byte, #@storeB" %} 5066 5067 ins_encode %{ 5068 __ sb(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5069 %} 5070 5071 ins_pipe(istore_reg_mem); 5072 %} 5073 5074 instruct storeimmB0(immI0 zero, memory mem) 5075 %{ 5076 match(Set mem (StoreB mem zero)); 5077 5078 ins_cost(STORE_COST); 5079 format %{ "sb zr, $mem\t# byte, #@storeimmB0" %} 5080 5081 ins_encode %{ 5082 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 5083 %} 5084 5085 ins_pipe(istore_mem); 5086 %} 5087 5088 // Store Char/Short 5089 instruct storeC(iRegIorL2I src, memory mem) 5090 %{ 5091 match(Set mem (StoreC mem src)); 5092 5093 ins_cost(STORE_COST); 5094 format %{ "sh $src, $mem\t# short, #@storeC" %} 5095 5096 ins_encode %{ 5097 __ sh(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5098 %} 5099 5100 ins_pipe(istore_reg_mem); 5101 %} 5102 5103 instruct storeimmC0(immI0 zero, memory mem) 5104 %{ 5105 match(Set mem (StoreC mem zero)); 5106 5107 ins_cost(STORE_COST); 5108 format %{ "sh zr, $mem\t# short, #@storeimmC0" %} 5109 5110 ins_encode %{ 5111 __ sh(zr, Address(as_Register($mem$$base), $mem$$disp)); 5112 %} 5113 5114 ins_pipe(istore_mem); 5115 %} 5116 5117 // Store Integer 5118 instruct storeI(iRegIorL2I src, memory mem) 5119 %{ 5120 match(Set mem(StoreI mem src)); 5121 5122 ins_cost(STORE_COST); 5123 format %{ "sw $src, $mem\t# int, #@storeI" %} 5124 5125 ins_encode %{ 5126 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5127 %} 5128 5129 ins_pipe(istore_reg_mem); 5130 %} 5131 5132 instruct storeimmI0(immI0 zero, memory mem) 5133 %{ 5134 match(Set mem(StoreI mem zero)); 5135 5136 ins_cost(STORE_COST); 5137 format %{ "sw zr, $mem\t# int, #@storeimmI0" %} 5138 5139 ins_encode %{ 5140 __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); 5141 %} 5142 5143 ins_pipe(istore_mem); 5144 %} 5145 5146 // Store Long (64 bit signed) 5147 instruct storeL(iRegL src, memory mem) 5148 %{ 5149 match(Set mem (StoreL mem src)); 5150 5151 ins_cost(STORE_COST); 5152 format %{ "sd $src, $mem\t# long, #@storeL" %} 5153 5154 ins_encode %{ 5155 __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5156 %} 5157 5158 ins_pipe(istore_reg_mem); 5159 %} 5160 5161 // Store Long (64 bit signed) 5162 instruct storeimmL0(immL0 zero, memory mem) 5163 %{ 5164 match(Set mem (StoreL mem zero)); 5165 5166 ins_cost(STORE_COST); 5167 format %{ "sd zr, $mem\t# long, #@storeimmL0" %} 5168 5169 ins_encode %{ 5170 __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); 5171 %} 5172 5173 ins_pipe(istore_mem); 5174 %} 5175 5176 // Store Pointer 5177 instruct storeP(iRegP src, memory mem) 5178 %{ 5179 match(Set mem (StoreP mem src)); 5180 predicate(n->as_Store()->barrier_data() == 0); 5181 5182 ins_cost(STORE_COST); 5183 format %{ "sd $src, $mem\t# ptr, #@storeP" %} 5184 5185 ins_encode %{ 5186 __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5187 %} 5188 5189 ins_pipe(istore_reg_mem); 5190 %} 5191 5192 // Store Pointer 5193 instruct storeimmP0(immP0 zero, memory mem) 5194 %{ 5195 match(Set mem (StoreP mem zero)); 5196 predicate(n->as_Store()->barrier_data() == 0); 5197 5198 ins_cost(STORE_COST); 5199 format %{ "sd zr, $mem\t# ptr, #@storeimmP0" %} 5200 5201 ins_encode %{ 5202 __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); 5203 %} 5204 5205 ins_pipe(istore_mem); 5206 %} 5207 5208 // Store Compressed Pointer 5209 instruct storeN(iRegN src, memory mem) 5210 %{ 5211 match(Set mem (StoreN mem src)); 5212 5213 ins_cost(STORE_COST); 5214 format %{ "sw $src, $mem\t# compressed ptr, #@storeN" %} 5215 5216 ins_encode %{ 5217 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5218 %} 5219 5220 ins_pipe(istore_reg_mem); 5221 %} 5222 5223 instruct storeImmN0(immN0 zero, memory mem) 5224 %{ 5225 match(Set mem (StoreN mem zero)); 5226 5227 ins_cost(STORE_COST); 5228 format %{ "sw zr, $mem\t# compressed ptr, #@storeImmN0" %} 5229 5230 ins_encode %{ 5231 __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); 5232 %} 5233 5234 ins_pipe(istore_reg_mem); 5235 %} 5236 5237 // Store Float 5238 instruct storeF(fRegF src, memory mem) 5239 %{ 5240 match(Set mem (StoreF mem src)); 5241 5242 ins_cost(STORE_COST); 5243 format %{ "fsw $src, $mem\t# float, #@storeF" %} 5244 5245 ins_encode %{ 5246 __ fsw(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5247 %} 5248 5249 ins_pipe(fp_store_reg_s); 5250 %} 5251 5252 // Store Double 5253 instruct storeD(fRegD src, memory mem) 5254 %{ 5255 match(Set mem (StoreD mem src)); 5256 5257 ins_cost(STORE_COST); 5258 format %{ "fsd $src, $mem\t# double, #@storeD" %} 5259 5260 ins_encode %{ 5261 __ fsd(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5262 %} 5263 5264 ins_pipe(fp_store_reg_d); 5265 %} 5266 5267 // Store Compressed Klass Pointer 5268 instruct storeNKlass(iRegN src, memory mem) 5269 %{ 5270 match(Set mem (StoreNKlass mem src)); 5271 5272 ins_cost(STORE_COST); 5273 format %{ "sw $src, $mem\t# compressed klass ptr, #@storeNKlass" %} 5274 5275 ins_encode %{ 5276 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5277 %} 5278 5279 ins_pipe(istore_reg_mem); 5280 %} 5281 5282 // ============================================================================ 5283 // Prefetch instructions 5284 // Must be safe to execute with invalid address (cannot fault). 5285 5286 instruct prefetchalloc( memory mem ) %{ 5287 predicate(UseZicbop); 5288 match(PrefetchAllocation mem); 5289 5290 ins_cost(ALU_COST * 1); 5291 format %{ "prefetch_w $mem\t# Prefetch for write" %} 5292 5293 ins_encode %{ 5294 if (Assembler::is_simm12($mem$$disp)) { 5295 if (($mem$$disp & 0x1f) == 0) { 5296 __ prefetch_w(as_Register($mem$$base), $mem$$disp); 5297 } else { 5298 __ addi(t0, as_Register($mem$$base), $mem$$disp); 5299 __ prefetch_w(t0, 0); 5300 } 5301 } else { 5302 __ mv(t0, $mem$$disp); 5303 __ add(t0, as_Register($mem$$base), t0); 5304 __ prefetch_w(t0, 0); 5305 } 5306 %} 5307 5308 ins_pipe(iload_prefetch); 5309 %} 5310 5311 // ============================================================================ 5312 // Atomic operation instructions 5313 // 5314 5315 // standard CompareAndSwapX when we are using barriers 5316 // these have higher priority than the rules selected by a predicate 5317 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5318 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5319 %{ 5320 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 5321 5322 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); 5323 5324 effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 5325 5326 format %{ 5327 "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" 5328 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB" 5329 %} 5330 5331 ins_encode %{ 5332 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5333 Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, 5334 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5335 %} 5336 5337 ins_pipe(pipe_slow); 5338 %} 5339 5340 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5341 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5342 %{ 5343 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 5344 5345 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); 5346 5347 effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 5348 5349 format %{ 5350 "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" 5351 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS" 5352 %} 5353 5354 ins_encode %{ 5355 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5356 Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, 5357 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5358 %} 5359 5360 ins_pipe(pipe_slow); 5361 %} 5362 5363 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5364 %{ 5365 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 5366 5367 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5368 5369 format %{ 5370 "cmpxchg $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" 5371 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapI" 5372 %} 5373 5374 ins_encode(riscv_enc_cmpxchgw(res, mem, oldval, newval)); 5375 5376 ins_pipe(pipe_slow); 5377 %} 5378 5379 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5380 %{ 5381 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 5382 5383 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5384 5385 format %{ 5386 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" 5387 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapL" 5388 %} 5389 5390 ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); 5391 5392 ins_pipe(pipe_slow); 5393 %} 5394 5395 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5396 %{ 5397 predicate(n->as_LoadStore()->barrier_data() == 0); 5398 5399 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 5400 5401 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5402 5403 format %{ 5404 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" 5405 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapP" 5406 %} 5407 5408 ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); 5409 5410 ins_pipe(pipe_slow); 5411 %} 5412 5413 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5414 %{ 5415 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 5416 5417 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); 5418 5419 format %{ 5420 "cmpxchg $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" 5421 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapN" 5422 %} 5423 5424 ins_encode(riscv_enc_cmpxchgn(res, mem, oldval, newval)); 5425 5426 ins_pipe(pipe_slow); 5427 %} 5428 5429 // alternative CompareAndSwapX when we are eliding barriers 5430 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5431 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5432 %{ 5433 predicate(needs_acquiring_load_reserved(n)); 5434 5435 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 5436 5437 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); 5438 5439 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5440 5441 format %{ 5442 "cmpxchg_acq $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" 5443 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq" 5444 %} 5445 5446 ins_encode %{ 5447 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5448 Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, 5449 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5450 %} 5451 5452 ins_pipe(pipe_slow); 5453 %} 5454 5455 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5456 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5457 %{ 5458 predicate(needs_acquiring_load_reserved(n)); 5459 5460 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 5461 5462 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); 5463 5464 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5465 5466 format %{ 5467 "cmpxchg_acq $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" 5468 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq" 5469 %} 5470 5471 ins_encode %{ 5472 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5473 Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, 5474 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5475 %} 5476 5477 ins_pipe(pipe_slow); 5478 %} 5479 5480 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5481 %{ 5482 predicate(needs_acquiring_load_reserved(n)); 5483 5484 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 5485 5486 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5487 5488 format %{ 5489 "cmpxchg_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" 5490 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapIAcq" 5491 %} 5492 5493 ins_encode(riscv_enc_cmpxchgw_acq(res, mem, oldval, newval)); 5494 5495 ins_pipe(pipe_slow); 5496 %} 5497 5498 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5499 %{ 5500 predicate(needs_acquiring_load_reserved(n)); 5501 5502 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 5503 5504 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5505 5506 format %{ 5507 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" 5508 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapLAcq" 5509 %} 5510 5511 ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); 5512 5513 ins_pipe(pipe_slow); 5514 %} 5515 5516 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5517 %{ 5518 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 5519 5520 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 5521 5522 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5523 5524 format %{ 5525 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" 5526 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapPAcq" 5527 %} 5528 5529 ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); 5530 5531 ins_pipe(pipe_slow); 5532 %} 5533 5534 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5535 %{ 5536 predicate(needs_acquiring_load_reserved(n)); 5537 5538 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 5539 5540 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); 5541 5542 format %{ 5543 "cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" 5544 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapNAcq" 5545 %} 5546 5547 ins_encode(riscv_enc_cmpxchgn_acq(res, mem, oldval, newval)); 5548 5549 ins_pipe(pipe_slow); 5550 %} 5551 5552 // Sundry CAS operations. Note that release is always true, 5553 // regardless of the memory ordering of the CAS. This is because we 5554 // need the volatile case to be sequentially consistent but there is 5555 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 5556 // can't check the type of memory ordering here, so we always emit a 5557 // sc_d(w) with rl bit set. 5558 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5559 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5560 %{ 5561 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 5562 5563 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); 5564 5565 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5566 5567 format %{ 5568 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB" 5569 %} 5570 5571 ins_encode %{ 5572 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5573 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5574 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5575 %} 5576 5577 ins_pipe(pipe_slow); 5578 %} 5579 5580 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5581 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5582 %{ 5583 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 5584 5585 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); 5586 5587 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5588 5589 format %{ 5590 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS" 5591 %} 5592 5593 ins_encode %{ 5594 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5595 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5596 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5597 %} 5598 5599 ins_pipe(pipe_slow); 5600 %} 5601 5602 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5603 %{ 5604 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 5605 5606 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5607 5608 effect(TEMP_DEF res); 5609 5610 format %{ 5611 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeI" 5612 %} 5613 5614 ins_encode %{ 5615 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5616 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5617 %} 5618 5619 ins_pipe(pipe_slow); 5620 %} 5621 5622 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) 5623 %{ 5624 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 5625 5626 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5627 5628 effect(TEMP_DEF res); 5629 5630 format %{ 5631 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeL" 5632 %} 5633 5634 ins_encode %{ 5635 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5636 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5637 %} 5638 5639 ins_pipe(pipe_slow); 5640 %} 5641 5642 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) 5643 %{ 5644 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 5645 5646 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 3); 5647 5648 effect(TEMP_DEF res); 5649 5650 format %{ 5651 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN" 5652 %} 5653 5654 ins_encode %{ 5655 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5656 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5657 %} 5658 5659 ins_pipe(pipe_slow); 5660 %} 5661 5662 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) 5663 %{ 5664 predicate(n->as_LoadStore()->barrier_data() == 0); 5665 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 5666 5667 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5668 5669 effect(TEMP_DEF res); 5670 5671 format %{ 5672 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeP" 5673 %} 5674 5675 ins_encode %{ 5676 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5677 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5678 %} 5679 5680 ins_pipe(pipe_slow); 5681 %} 5682 5683 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5684 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5685 %{ 5686 predicate(needs_acquiring_load_reserved(n)); 5687 5688 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 5689 5690 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); 5691 5692 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5693 5694 format %{ 5695 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq" 5696 %} 5697 5698 ins_encode %{ 5699 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5700 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5701 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5702 %} 5703 5704 ins_pipe(pipe_slow); 5705 %} 5706 5707 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5708 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5709 %{ 5710 predicate(needs_acquiring_load_reserved(n)); 5711 5712 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 5713 5714 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); 5715 5716 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5717 5718 format %{ 5719 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq" 5720 %} 5721 5722 ins_encode %{ 5723 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5724 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5725 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5726 %} 5727 5728 ins_pipe(pipe_slow); 5729 %} 5730 5731 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5732 %{ 5733 predicate(needs_acquiring_load_reserved(n)); 5734 5735 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 5736 5737 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5738 5739 effect(TEMP_DEF res); 5740 5741 format %{ 5742 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeIAcq" 5743 %} 5744 5745 ins_encode %{ 5746 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5747 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5748 %} 5749 5750 ins_pipe(pipe_slow); 5751 %} 5752 5753 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) 5754 %{ 5755 predicate(needs_acquiring_load_reserved(n)); 5756 5757 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 5758 5759 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5760 5761 effect(TEMP_DEF res); 5762 5763 format %{ 5764 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeLAcq" 5765 %} 5766 5767 ins_encode %{ 5768 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5769 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5770 %} 5771 5772 ins_pipe(pipe_slow); 5773 %} 5774 5775 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) 5776 %{ 5777 predicate(needs_acquiring_load_reserved(n)); 5778 5779 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 5780 5781 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5782 5783 effect(TEMP_DEF res); 5784 5785 format %{ 5786 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq" 5787 %} 5788 5789 ins_encode %{ 5790 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5791 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5792 %} 5793 5794 ins_pipe(pipe_slow); 5795 %} 5796 5797 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) 5798 %{ 5799 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 5800 5801 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 5802 5803 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5804 5805 effect(TEMP_DEF res); 5806 5807 format %{ 5808 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq" 5809 %} 5810 5811 ins_encode %{ 5812 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5813 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5814 %} 5815 5816 ins_pipe(pipe_slow); 5817 %} 5818 5819 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5820 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5821 %{ 5822 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 5823 5824 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); 5825 5826 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5827 5828 format %{ 5829 "cmpxchg_weak $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5830 "# $res == 1 when success, #@weakCompareAndSwapB" 5831 %} 5832 5833 ins_encode %{ 5834 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5835 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5836 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5837 %} 5838 5839 ins_pipe(pipe_slow); 5840 %} 5841 5842 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5843 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5844 %{ 5845 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 5846 5847 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); 5848 5849 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5850 5851 format %{ 5852 "cmpxchg_weak $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5853 "# $res == 1 when success, #@weakCompareAndSwapS" 5854 %} 5855 5856 ins_encode %{ 5857 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5858 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5859 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5860 %} 5861 5862 ins_pipe(pipe_slow); 5863 %} 5864 5865 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5866 %{ 5867 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 5868 5869 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5870 5871 format %{ 5872 "cmpxchg_weak $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5873 "# $res == 1 when success, #@weakCompareAndSwapI" 5874 %} 5875 5876 ins_encode %{ 5877 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5878 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5879 %} 5880 5881 ins_pipe(pipe_slow); 5882 %} 5883 5884 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5885 %{ 5886 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 5887 5888 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5889 5890 format %{ 5891 "cmpxchg_weak $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5892 "# $res == 1 when success, #@weakCompareAndSwapL" 5893 %} 5894 5895 ins_encode %{ 5896 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5897 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5898 %} 5899 5900 ins_pipe(pipe_slow); 5901 %} 5902 5903 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5904 %{ 5905 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 5906 5907 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); 5908 5909 format %{ 5910 "cmpxchg_weak $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5911 "# $res == 1 when success, #@weakCompareAndSwapN" 5912 %} 5913 5914 ins_encode %{ 5915 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5916 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5917 %} 5918 5919 ins_pipe(pipe_slow); 5920 %} 5921 5922 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5923 %{ 5924 predicate(n->as_LoadStore()->barrier_data() == 0); 5925 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 5926 5927 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5928 5929 format %{ 5930 "cmpxchg_weak $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5931 "# $res == 1 when success, #@weakCompareAndSwapP" 5932 %} 5933 5934 ins_encode %{ 5935 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5936 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5937 %} 5938 5939 ins_pipe(pipe_slow); 5940 %} 5941 5942 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5943 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5944 %{ 5945 predicate(needs_acquiring_load_reserved(n)); 5946 5947 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 5948 5949 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); 5950 5951 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5952 5953 format %{ 5954 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5955 "# $res == 1 when success, #@weakCompareAndSwapBAcq" 5956 %} 5957 5958 ins_encode %{ 5959 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5960 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5961 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5962 %} 5963 5964 ins_pipe(pipe_slow); 5965 %} 5966 5967 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5968 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5969 %{ 5970 predicate(needs_acquiring_load_reserved(n)); 5971 5972 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 5973 5974 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); 5975 5976 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5977 5978 format %{ 5979 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5980 "# $res == 1 when success, #@weakCompareAndSwapSAcq" 5981 %} 5982 5983 ins_encode %{ 5984 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5985 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5986 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5987 %} 5988 5989 ins_pipe(pipe_slow); 5990 %} 5991 5992 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5993 %{ 5994 predicate(needs_acquiring_load_reserved(n)); 5995 5996 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 5997 5998 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5999 6000 format %{ 6001 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" 6002 "# $res == 1 when success, #@weakCompareAndSwapIAcq" 6003 %} 6004 6005 ins_encode %{ 6006 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 6007 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 6008 %} 6009 6010 ins_pipe(pipe_slow); 6011 %} 6012 6013 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 6014 %{ 6015 predicate(needs_acquiring_load_reserved(n)); 6016 6017 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 6018 6019 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 6020 6021 format %{ 6022 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" 6023 "# $res == 1 when success, #@weakCompareAndSwapLAcq" 6024 %} 6025 6026 ins_encode %{ 6027 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 6028 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 6029 %} 6030 6031 ins_pipe(pipe_slow); 6032 %} 6033 6034 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 6035 %{ 6036 predicate(needs_acquiring_load_reserved(n)); 6037 6038 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 6039 6040 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); 6041 6042 format %{ 6043 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" 6044 "# $res == 1 when success, #@weakCompareAndSwapNAcq" 6045 %} 6046 6047 ins_encode %{ 6048 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 6049 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 6050 %} 6051 6052 ins_pipe(pipe_slow); 6053 %} 6054 6055 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 6056 %{ 6057 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 6058 6059 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 6060 6061 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 6062 6063 format %{ 6064 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" 6065 "\t# $res == 1 when success, #@weakCompareAndSwapPAcq" 6066 %} 6067 6068 ins_encode %{ 6069 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 6070 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 6071 %} 6072 6073 ins_pipe(pipe_slow); 6074 %} 6075 6076 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) 6077 %{ 6078 match(Set prev (GetAndSetI mem newv)); 6079 6080 ins_cost(ALU_COST); 6081 6082 format %{ "atomic_xchgw $prev, $newv, [$mem]\t#@get_and_setI" %} 6083 6084 ins_encode %{ 6085 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6086 %} 6087 6088 ins_pipe(pipe_serial); 6089 %} 6090 6091 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) 6092 %{ 6093 match(Set prev (GetAndSetL mem newv)); 6094 6095 ins_cost(ALU_COST); 6096 6097 format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setL" %} 6098 6099 ins_encode %{ 6100 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6101 %} 6102 6103 ins_pipe(pipe_serial); 6104 %} 6105 6106 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) 6107 %{ 6108 match(Set prev (GetAndSetN mem newv)); 6109 6110 ins_cost(ALU_COST); 6111 6112 format %{ "atomic_xchgwu $prev, $newv, [$mem]\t#@get_and_setN" %} 6113 6114 ins_encode %{ 6115 __ atomic_xchgwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6116 %} 6117 6118 ins_pipe(pipe_serial); 6119 %} 6120 6121 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) 6122 %{ 6123 predicate(n->as_LoadStore()->barrier_data() == 0); 6124 match(Set prev (GetAndSetP mem newv)); 6125 6126 ins_cost(ALU_COST); 6127 6128 format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setP" %} 6129 6130 ins_encode %{ 6131 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6132 %} 6133 6134 ins_pipe(pipe_serial); 6135 %} 6136 6137 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) 6138 %{ 6139 predicate(needs_acquiring_load_reserved(n)); 6140 6141 match(Set prev (GetAndSetI mem newv)); 6142 6143 ins_cost(ALU_COST); 6144 6145 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]\t#@get_and_setIAcq" %} 6146 6147 ins_encode %{ 6148 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6149 %} 6150 6151 ins_pipe(pipe_serial); 6152 %} 6153 6154 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) 6155 %{ 6156 predicate(needs_acquiring_load_reserved(n)); 6157 6158 match(Set prev (GetAndSetL mem newv)); 6159 6160 ins_cost(ALU_COST); 6161 6162 format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setLAcq" %} 6163 6164 ins_encode %{ 6165 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6166 %} 6167 6168 ins_pipe(pipe_serial); 6169 %} 6170 6171 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) 6172 %{ 6173 predicate(needs_acquiring_load_reserved(n)); 6174 6175 match(Set prev (GetAndSetN mem newv)); 6176 6177 ins_cost(ALU_COST); 6178 6179 format %{ "atomic_xchgwu_acq $prev, $newv, [$mem]\t#@get_and_setNAcq" %} 6180 6181 ins_encode %{ 6182 __ atomic_xchgalwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6183 %} 6184 6185 ins_pipe(pipe_serial); 6186 %} 6187 6188 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) 6189 %{ 6190 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 6191 6192 match(Set prev (GetAndSetP mem newv)); 6193 6194 ins_cost(ALU_COST); 6195 6196 format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setPAcq" %} 6197 6198 ins_encode %{ 6199 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6200 %} 6201 6202 ins_pipe(pipe_serial); 6203 %} 6204 6205 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) 6206 %{ 6207 match(Set newval (GetAndAddL mem incr)); 6208 6209 ins_cost(ALU_COST); 6210 6211 format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addL" %} 6212 6213 ins_encode %{ 6214 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6215 %} 6216 6217 ins_pipe(pipe_serial); 6218 %} 6219 6220 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) 6221 %{ 6222 predicate(n->as_LoadStore()->result_not_used()); 6223 6224 match(Set dummy (GetAndAddL mem incr)); 6225 6226 ins_cost(ALU_COST); 6227 6228 format %{ "get_and_addL [$mem], $incr\t#@get_and_addL_no_res" %} 6229 6230 ins_encode %{ 6231 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 6232 %} 6233 6234 ins_pipe(pipe_serial); 6235 %} 6236 6237 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAdd incr) 6238 %{ 6239 match(Set newval (GetAndAddL mem incr)); 6240 6241 ins_cost(ALU_COST); 6242 6243 format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addLi" %} 6244 6245 ins_encode %{ 6246 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6247 %} 6248 6249 ins_pipe(pipe_serial); 6250 %} 6251 6252 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAdd incr) 6253 %{ 6254 predicate(n->as_LoadStore()->result_not_used()); 6255 6256 match(Set dummy (GetAndAddL mem incr)); 6257 6258 ins_cost(ALU_COST); 6259 6260 format %{ "get_and_addL [$mem], $incr\t#@get_and_addLi_no_res" %} 6261 6262 ins_encode %{ 6263 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 6264 %} 6265 6266 ins_pipe(pipe_serial); 6267 %} 6268 6269 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) 6270 %{ 6271 match(Set newval (GetAndAddI mem incr)); 6272 6273 ins_cost(ALU_COST); 6274 6275 format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addI" %} 6276 6277 ins_encode %{ 6278 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6279 %} 6280 6281 ins_pipe(pipe_serial); 6282 %} 6283 6284 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) 6285 %{ 6286 predicate(n->as_LoadStore()->result_not_used()); 6287 6288 match(Set dummy (GetAndAddI mem incr)); 6289 6290 ins_cost(ALU_COST); 6291 6292 format %{ "get_and_addI [$mem], $incr\t#@get_and_addI_no_res" %} 6293 6294 ins_encode %{ 6295 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 6296 %} 6297 6298 ins_pipe(pipe_serial); 6299 %} 6300 6301 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAdd incr) 6302 %{ 6303 match(Set newval (GetAndAddI mem incr)); 6304 6305 ins_cost(ALU_COST); 6306 6307 format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addIi" %} 6308 6309 ins_encode %{ 6310 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6311 %} 6312 6313 ins_pipe(pipe_serial); 6314 %} 6315 6316 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAdd incr) 6317 %{ 6318 predicate(n->as_LoadStore()->result_not_used()); 6319 6320 match(Set dummy (GetAndAddI mem incr)); 6321 6322 ins_cost(ALU_COST); 6323 6324 format %{ "get_and_addI [$mem], $incr\t#@get_and_addIi_no_res" %} 6325 6326 ins_encode %{ 6327 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 6328 %} 6329 6330 ins_pipe(pipe_serial); 6331 %} 6332 6333 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) 6334 %{ 6335 predicate(needs_acquiring_load_reserved(n)); 6336 6337 match(Set newval (GetAndAddL mem incr)); 6338 6339 ins_cost(ALU_COST); 6340 6341 format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLAcq" %} 6342 6343 ins_encode %{ 6344 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6345 %} 6346 6347 ins_pipe(pipe_serial); 6348 %} 6349 6350 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 6351 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6352 6353 match(Set dummy (GetAndAddL mem incr)); 6354 6355 ins_cost(ALU_COST); 6356 6357 format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addL_no_resAcq" %} 6358 6359 ins_encode %{ 6360 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 6361 %} 6362 6363 ins_pipe(pipe_serial); 6364 %} 6365 6366 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAdd incr) 6367 %{ 6368 predicate(needs_acquiring_load_reserved(n)); 6369 6370 match(Set newval (GetAndAddL mem incr)); 6371 6372 ins_cost(ALU_COST); 6373 6374 format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLiAcq" %} 6375 6376 ins_encode %{ 6377 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6378 %} 6379 6380 ins_pipe(pipe_serial); 6381 %} 6382 6383 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAdd incr) 6384 %{ 6385 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6386 6387 match(Set dummy (GetAndAddL mem incr)); 6388 6389 ins_cost(ALU_COST); 6390 6391 format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addLi_no_resAcq" %} 6392 6393 ins_encode %{ 6394 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 6395 %} 6396 6397 ins_pipe(pipe_serial); 6398 %} 6399 6400 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) 6401 %{ 6402 predicate(needs_acquiring_load_reserved(n)); 6403 6404 match(Set newval (GetAndAddI mem incr)); 6405 6406 ins_cost(ALU_COST); 6407 6408 format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIAcq" %} 6409 6410 ins_encode %{ 6411 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6412 %} 6413 6414 ins_pipe(pipe_serial); 6415 %} 6416 6417 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) 6418 %{ 6419 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6420 6421 match(Set dummy (GetAndAddI mem incr)); 6422 6423 ins_cost(ALU_COST); 6424 6425 format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addI_no_resAcq" %} 6426 6427 ins_encode %{ 6428 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 6429 %} 6430 6431 ins_pipe(pipe_serial); 6432 %} 6433 6434 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAdd incr) 6435 %{ 6436 predicate(needs_acquiring_load_reserved(n)); 6437 6438 match(Set newval (GetAndAddI mem incr)); 6439 6440 ins_cost(ALU_COST); 6441 6442 format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIiAcq" %} 6443 6444 ins_encode %{ 6445 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6446 %} 6447 6448 ins_pipe(pipe_serial); 6449 %} 6450 6451 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAdd incr) 6452 %{ 6453 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6454 6455 match(Set dummy (GetAndAddI mem incr)); 6456 6457 ins_cost(ALU_COST); 6458 6459 format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addIi_no_resAcq" %} 6460 6461 ins_encode %{ 6462 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 6463 %} 6464 6465 ins_pipe(pipe_serial); 6466 %} 6467 6468 // ============================================================================ 6469 // Arithmetic Instructions 6470 // 6471 6472 // Integer Addition 6473 6474 // TODO 6475 // these currently employ operations which do not set CR and hence are 6476 // not flagged as killing CR but we would like to isolate the cases 6477 // where we want to set flags from those where we don't. need to work 6478 // out how to do that. 6479 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6480 match(Set dst (AddI src1 src2)); 6481 6482 ins_cost(ALU_COST); 6483 format %{ "addw $dst, $src1, $src2\t#@addI_reg_reg" %} 6484 6485 ins_encode %{ 6486 __ addw(as_Register($dst$$reg), 6487 as_Register($src1$$reg), 6488 as_Register($src2$$reg)); 6489 %} 6490 6491 ins_pipe(ialu_reg_reg); 6492 %} 6493 6494 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAdd src2) %{ 6495 match(Set dst (AddI src1 src2)); 6496 6497 ins_cost(ALU_COST); 6498 format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm" %} 6499 6500 ins_encode %{ 6501 int32_t con = (int32_t)$src2$$constant; 6502 __ addiw(as_Register($dst$$reg), 6503 as_Register($src1$$reg), 6504 $src2$$constant); 6505 %} 6506 6507 ins_pipe(ialu_reg_imm); 6508 %} 6509 6510 instruct addI_reg_imm_l2i(iRegINoSp dst, iRegL src1, immIAdd src2) %{ 6511 match(Set dst (AddI (ConvL2I src1) src2)); 6512 6513 ins_cost(ALU_COST); 6514 format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm_l2i" %} 6515 6516 ins_encode %{ 6517 __ addiw(as_Register($dst$$reg), 6518 as_Register($src1$$reg), 6519 $src2$$constant); 6520 %} 6521 6522 ins_pipe(ialu_reg_imm); 6523 %} 6524 6525 // Pointer Addition 6526 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 6527 match(Set dst (AddP src1 src2)); 6528 6529 ins_cost(ALU_COST); 6530 format %{ "add $dst, $src1, $src2\t# ptr, #@addP_reg_reg" %} 6531 6532 ins_encode %{ 6533 __ add(as_Register($dst$$reg), 6534 as_Register($src1$$reg), 6535 as_Register($src2$$reg)); 6536 %} 6537 6538 ins_pipe(ialu_reg_reg); 6539 %} 6540 6541 // If we shift more than 32 bits, we need not convert I2L. 6542 instruct lShiftL_regI_immGE32(iRegLNoSp dst, iRegI src, uimmI6_ge32 scale) %{ 6543 match(Set dst (LShiftL (ConvI2L src) scale)); 6544 ins_cost(ALU_COST); 6545 format %{ "slli $dst, $src, $scale & 63\t#@lShiftL_regI_immGE32" %} 6546 6547 ins_encode %{ 6548 __ slli(as_Register($dst$$reg), as_Register($src$$reg), $scale$$constant & 63); 6549 %} 6550 6551 ins_pipe(ialu_reg_shift); 6552 %} 6553 6554 // Pointer Immediate Addition 6555 // n.b. this needs to be more expensive than using an indirect memory 6556 // operand 6557 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{ 6558 match(Set dst (AddP src1 src2)); 6559 ins_cost(ALU_COST); 6560 format %{ "addi $dst, $src1, $src2\t# ptr, #@addP_reg_imm" %} 6561 6562 ins_encode %{ 6563 // src2 is imm, so actually call the addi 6564 __ add(as_Register($dst$$reg), 6565 as_Register($src1$$reg), 6566 $src2$$constant); 6567 %} 6568 6569 ins_pipe(ialu_reg_imm); 6570 %} 6571 6572 // Long Addition 6573 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6574 match(Set dst (AddL src1 src2)); 6575 ins_cost(ALU_COST); 6576 format %{ "add $dst, $src1, $src2\t#@addL_reg_reg" %} 6577 6578 ins_encode %{ 6579 __ add(as_Register($dst$$reg), 6580 as_Register($src1$$reg), 6581 as_Register($src2$$reg)); 6582 %} 6583 6584 ins_pipe(ialu_reg_reg); 6585 %} 6586 6587 // No constant pool entries requiredLong Immediate Addition. 6588 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 6589 match(Set dst (AddL src1 src2)); 6590 ins_cost(ALU_COST); 6591 format %{ "addi $dst, $src1, $src2\t#@addL_reg_imm" %} 6592 6593 ins_encode %{ 6594 // src2 is imm, so actually call the addi 6595 __ add(as_Register($dst$$reg), 6596 as_Register($src1$$reg), 6597 $src2$$constant); 6598 %} 6599 6600 ins_pipe(ialu_reg_imm); 6601 %} 6602 6603 // Integer Subtraction 6604 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6605 match(Set dst (SubI src1 src2)); 6606 6607 ins_cost(ALU_COST); 6608 format %{ "subw $dst, $src1, $src2\t#@subI_reg_reg" %} 6609 6610 ins_encode %{ 6611 __ subw(as_Register($dst$$reg), 6612 as_Register($src1$$reg), 6613 as_Register($src2$$reg)); 6614 %} 6615 6616 ins_pipe(ialu_reg_reg); 6617 %} 6618 6619 // Immediate Subtraction 6620 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{ 6621 match(Set dst (SubI src1 src2)); 6622 6623 ins_cost(ALU_COST); 6624 format %{ "addiw $dst, $src1, -$src2\t#@subI_reg_imm" %} 6625 6626 ins_encode %{ 6627 // src2 is imm, so actually call the addiw 6628 __ subw(as_Register($dst$$reg), 6629 as_Register($src1$$reg), 6630 $src2$$constant); 6631 %} 6632 6633 ins_pipe(ialu_reg_imm); 6634 %} 6635 6636 // Long Subtraction 6637 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6638 match(Set dst (SubL src1 src2)); 6639 ins_cost(ALU_COST); 6640 format %{ "sub $dst, $src1, $src2\t#@subL_reg_reg" %} 6641 6642 ins_encode %{ 6643 __ sub(as_Register($dst$$reg), 6644 as_Register($src1$$reg), 6645 as_Register($src2$$reg)); 6646 %} 6647 6648 ins_pipe(ialu_reg_reg); 6649 %} 6650 6651 // No constant pool entries requiredLong Immediate Subtraction. 6652 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{ 6653 match(Set dst (SubL src1 src2)); 6654 ins_cost(ALU_COST); 6655 format %{ "addi $dst, $src1, -$src2\t#@subL_reg_imm" %} 6656 6657 ins_encode %{ 6658 // src2 is imm, so actually call the addi 6659 __ sub(as_Register($dst$$reg), 6660 as_Register($src1$$reg), 6661 $src2$$constant); 6662 %} 6663 6664 ins_pipe(ialu_reg_imm); 6665 %} 6666 6667 // Integer Negation (special case for sub) 6668 6669 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 6670 match(Set dst (SubI zero src)); 6671 ins_cost(ALU_COST); 6672 format %{ "subw $dst, x0, $src\t# int, #@negI_reg" %} 6673 6674 ins_encode %{ 6675 // actually call the subw 6676 __ negw(as_Register($dst$$reg), 6677 as_Register($src$$reg)); 6678 %} 6679 6680 ins_pipe(ialu_reg); 6681 %} 6682 6683 // Long Negation 6684 6685 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero) %{ 6686 match(Set dst (SubL zero src)); 6687 ins_cost(ALU_COST); 6688 format %{ "sub $dst, x0, $src\t# long, #@negL_reg" %} 6689 6690 ins_encode %{ 6691 // actually call the sub 6692 __ neg(as_Register($dst$$reg), 6693 as_Register($src$$reg)); 6694 %} 6695 6696 ins_pipe(ialu_reg); 6697 %} 6698 6699 // Integer Multiply 6700 6701 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6702 match(Set dst (MulI src1 src2)); 6703 ins_cost(IMUL_COST); 6704 format %{ "mulw $dst, $src1, $src2\t#@mulI" %} 6705 6706 //this means 2 word multi, and no sign extend to 64 bits 6707 ins_encode %{ 6708 // riscv64 mulw will sign-extension to high 32 bits in dst reg 6709 __ mulw(as_Register($dst$$reg), 6710 as_Register($src1$$reg), 6711 as_Register($src2$$reg)); 6712 %} 6713 6714 ins_pipe(imul_reg_reg); 6715 %} 6716 6717 // Long Multiply 6718 6719 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6720 match(Set dst (MulL src1 src2)); 6721 ins_cost(IMUL_COST); 6722 format %{ "mul $dst, $src1, $src2\t#@mulL" %} 6723 6724 ins_encode %{ 6725 __ mul(as_Register($dst$$reg), 6726 as_Register($src1$$reg), 6727 as_Register($src2$$reg)); 6728 %} 6729 6730 ins_pipe(lmul_reg_reg); 6731 %} 6732 6733 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) 6734 %{ 6735 match(Set dst (MulHiL src1 src2)); 6736 ins_cost(IMUL_COST); 6737 format %{ "mulh $dst, $src1, $src2\t# mulhi, #@mulHiL_rReg" %} 6738 6739 ins_encode %{ 6740 __ mulh(as_Register($dst$$reg), 6741 as_Register($src1$$reg), 6742 as_Register($src2$$reg)); 6743 %} 6744 6745 ins_pipe(lmul_reg_reg); 6746 %} 6747 6748 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) 6749 %{ 6750 match(Set dst (UMulHiL src1 src2)); 6751 ins_cost(IMUL_COST); 6752 format %{ "mulhu $dst, $src1, $src2\t# umulhi, #@umulHiL_rReg" %} 6753 6754 ins_encode %{ 6755 __ mulhu(as_Register($dst$$reg), 6756 as_Register($src1$$reg), 6757 as_Register($src2$$reg)); 6758 %} 6759 6760 ins_pipe(lmul_reg_reg); 6761 %} 6762 6763 // Integer Divide 6764 6765 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6766 match(Set dst (DivI src1 src2)); 6767 ins_cost(IDIVSI_COST); 6768 format %{ "divw $dst, $src1, $src2\t#@divI"%} 6769 6770 ins_encode(riscv_enc_divw(dst, src1, src2)); 6771 ins_pipe(idiv_reg_reg); 6772 %} 6773 6774 instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6775 match(Set dst (UDivI src1 src2)); 6776 ins_cost(IDIVSI_COST); 6777 format %{ "divuw $dst, $src1, $src2\t#@UdivI"%} 6778 6779 ins_encode(riscv_enc_divuw(dst, src1, src2)); 6780 ins_pipe(idiv_reg_reg); 6781 %} 6782 6783 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 6784 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 6785 ins_cost(ALU_COST); 6786 format %{ "srliw $dst, $src1, $div1\t# int signExtract, #@signExtract" %} 6787 6788 ins_encode %{ 6789 __ srliw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 6790 %} 6791 ins_pipe(ialu_reg_shift); 6792 %} 6793 6794 // Long Divide 6795 6796 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6797 match(Set dst (DivL src1 src2)); 6798 ins_cost(IDIVDI_COST); 6799 format %{ "div $dst, $src1, $src2\t#@divL" %} 6800 6801 ins_encode(riscv_enc_div(dst, src1, src2)); 6802 ins_pipe(ldiv_reg_reg); 6803 %} 6804 6805 instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6806 match(Set dst (UDivL src1 src2)); 6807 ins_cost(IDIVDI_COST); 6808 6809 format %{ "divu $dst, $src1, $src2\t#@UdivL" %} 6810 6811 ins_encode(riscv_enc_divu(dst, src1, src2)); 6812 ins_pipe(ldiv_reg_reg); 6813 %} 6814 6815 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 6816 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 6817 ins_cost(ALU_COST); 6818 format %{ "srli $dst, $src1, $div1\t# long signExtract, #@signExtractL" %} 6819 6820 ins_encode %{ 6821 __ srli(as_Register($dst$$reg), as_Register($src1$$reg), 63); 6822 %} 6823 ins_pipe(ialu_reg_shift); 6824 %} 6825 6826 // Integer Remainder 6827 6828 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6829 match(Set dst (ModI src1 src2)); 6830 ins_cost(IDIVSI_COST); 6831 format %{ "remw $dst, $src1, $src2\t#@modI" %} 6832 6833 ins_encode(riscv_enc_modw(dst, src1, src2)); 6834 ins_pipe(ialu_reg_reg); 6835 %} 6836 6837 instruct UmodI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6838 match(Set dst (UModI src1 src2)); 6839 ins_cost(IDIVSI_COST); 6840 format %{ "remuw $dst, $src1, $src2\t#@UmodI" %} 6841 6842 ins_encode(riscv_enc_moduw(dst, src1, src2)); 6843 ins_pipe(ialu_reg_reg); 6844 %} 6845 6846 // Long Remainder 6847 6848 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6849 match(Set dst (ModL src1 src2)); 6850 ins_cost(IDIVDI_COST); 6851 format %{ "rem $dst, $src1, $src2\t#@modL" %} 6852 6853 ins_encode(riscv_enc_mod(dst, src1, src2)); 6854 ins_pipe(ialu_reg_reg); 6855 %} 6856 6857 instruct UmodL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6858 match(Set dst (UModL src1 src2)); 6859 ins_cost(IDIVDI_COST); 6860 format %{ "remu $dst, $src1, $src2\t#@UmodL" %} 6861 6862 ins_encode(riscv_enc_modu(dst, src1, src2)); 6863 ins_pipe(ialu_reg_reg); 6864 %} 6865 6866 // Integer Shifts 6867 6868 // Shift Left Register 6869 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6870 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6871 match(Set dst (LShiftI src1 src2)); 6872 ins_cost(ALU_COST); 6873 format %{ "sllw $dst, $src1, $src2\t#@lShiftI_reg_reg" %} 6874 6875 ins_encode %{ 6876 __ sllw(as_Register($dst$$reg), 6877 as_Register($src1$$reg), 6878 as_Register($src2$$reg)); 6879 %} 6880 6881 ins_pipe(ialu_reg_reg_vshift); 6882 %} 6883 6884 // Shift Left Immediate 6885 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6886 match(Set dst (LShiftI src1 src2)); 6887 ins_cost(ALU_COST); 6888 format %{ "slliw $dst, $src1, ($src2 & 0x1f)\t#@lShiftI_reg_imm" %} 6889 6890 ins_encode %{ 6891 // the shift amount is encoded in the lower 6892 // 5 bits of the I-immediate field for RV32I 6893 __ slliw(as_Register($dst$$reg), 6894 as_Register($src1$$reg), 6895 (unsigned) $src2$$constant & 0x1f); 6896 %} 6897 6898 ins_pipe(ialu_reg_shift); 6899 %} 6900 6901 // Shift Right Logical Register 6902 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6903 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6904 match(Set dst (URShiftI src1 src2)); 6905 ins_cost(ALU_COST); 6906 format %{ "srlw $dst, $src1, $src2\t#@urShiftI_reg_reg" %} 6907 6908 ins_encode %{ 6909 __ srlw(as_Register($dst$$reg), 6910 as_Register($src1$$reg), 6911 as_Register($src2$$reg)); 6912 %} 6913 6914 ins_pipe(ialu_reg_reg_vshift); 6915 %} 6916 6917 // Shift Right Logical Immediate 6918 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6919 match(Set dst (URShiftI src1 src2)); 6920 ins_cost(ALU_COST); 6921 format %{ "srliw $dst, $src1, ($src2 & 0x1f)\t#@urShiftI_reg_imm" %} 6922 6923 ins_encode %{ 6924 // the shift amount is encoded in the lower 6925 // 6 bits of the I-immediate field for RV64I 6926 __ srliw(as_Register($dst$$reg), 6927 as_Register($src1$$reg), 6928 (unsigned) $src2$$constant & 0x1f); 6929 %} 6930 6931 ins_pipe(ialu_reg_shift); 6932 %} 6933 6934 // Shift Right Arithmetic Register 6935 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6936 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6937 match(Set dst (RShiftI src1 src2)); 6938 ins_cost(ALU_COST); 6939 format %{ "sraw $dst, $src1, $src2\t#@rShiftI_reg_reg" %} 6940 6941 ins_encode %{ 6942 // riscv will sign-ext dst high 32 bits 6943 __ sraw(as_Register($dst$$reg), 6944 as_Register($src1$$reg), 6945 as_Register($src2$$reg)); 6946 %} 6947 6948 ins_pipe(ialu_reg_reg_vshift); 6949 %} 6950 6951 // Shift Right Arithmetic Immediate 6952 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6953 match(Set dst (RShiftI src1 src2)); 6954 ins_cost(ALU_COST); 6955 format %{ "sraiw $dst, $src1, ($src2 & 0x1f)\t#@rShiftI_reg_imm" %} 6956 6957 ins_encode %{ 6958 // riscv will sign-ext dst high 32 bits 6959 __ sraiw(as_Register($dst$$reg), 6960 as_Register($src1$$reg), 6961 (unsigned) $src2$$constant & 0x1f); 6962 %} 6963 6964 ins_pipe(ialu_reg_shift); 6965 %} 6966 6967 // Long Shifts 6968 6969 // Shift Left Register 6970 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 6971 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 6972 match(Set dst (LShiftL src1 src2)); 6973 6974 ins_cost(ALU_COST); 6975 format %{ "sll $dst, $src1, $src2\t#@lShiftL_reg_reg" %} 6976 6977 ins_encode %{ 6978 __ sll(as_Register($dst$$reg), 6979 as_Register($src1$$reg), 6980 as_Register($src2$$reg)); 6981 %} 6982 6983 ins_pipe(ialu_reg_reg_vshift); 6984 %} 6985 6986 // Shift Left Immediate 6987 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 6988 match(Set dst (LShiftL src1 src2)); 6989 6990 ins_cost(ALU_COST); 6991 format %{ "slli $dst, $src1, ($src2 & 0x3f)\t#@lShiftL_reg_imm" %} 6992 6993 ins_encode %{ 6994 // the shift amount is encoded in the lower 6995 // 6 bits of the I-immediate field for RV64I 6996 __ slli(as_Register($dst$$reg), 6997 as_Register($src1$$reg), 6998 (unsigned) $src2$$constant & 0x3f); 6999 %} 7000 7001 ins_pipe(ialu_reg_shift); 7002 %} 7003 7004 // Shift Right Logical Register 7005 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 7006 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 7007 match(Set dst (URShiftL src1 src2)); 7008 7009 ins_cost(ALU_COST); 7010 format %{ "srl $dst, $src1, $src2\t#@urShiftL_reg_reg" %} 7011 7012 ins_encode %{ 7013 __ srl(as_Register($dst$$reg), 7014 as_Register($src1$$reg), 7015 as_Register($src2$$reg)); 7016 %} 7017 7018 ins_pipe(ialu_reg_reg_vshift); 7019 %} 7020 7021 // Shift Right Logical Immediate 7022 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 7023 match(Set dst (URShiftL src1 src2)); 7024 7025 ins_cost(ALU_COST); 7026 format %{ "srli $dst, $src1, ($src2 & 0x3f)\t#@urShiftL_reg_imm" %} 7027 7028 ins_encode %{ 7029 // the shift amount is encoded in the lower 7030 // 6 bits of the I-immediate field for RV64I 7031 __ srli(as_Register($dst$$reg), 7032 as_Register($src1$$reg), 7033 (unsigned) $src2$$constant & 0x3f); 7034 %} 7035 7036 ins_pipe(ialu_reg_shift); 7037 %} 7038 7039 // A special-case pattern for card table stores. 7040 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 7041 match(Set dst (URShiftL (CastP2X src1) src2)); 7042 7043 ins_cost(ALU_COST); 7044 format %{ "srli $dst, p2x($src1), ($src2 & 0x3f)\t#@urShiftP_reg_imm" %} 7045 7046 ins_encode %{ 7047 // the shift amount is encoded in the lower 7048 // 6 bits of the I-immediate field for RV64I 7049 __ srli(as_Register($dst$$reg), 7050 as_Register($src1$$reg), 7051 (unsigned) $src2$$constant & 0x3f); 7052 %} 7053 7054 ins_pipe(ialu_reg_shift); 7055 %} 7056 7057 // Shift Right Arithmetic Register 7058 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 7059 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 7060 match(Set dst (RShiftL src1 src2)); 7061 7062 ins_cost(ALU_COST); 7063 format %{ "sra $dst, $src1, $src2\t#@rShiftL_reg_reg" %} 7064 7065 ins_encode %{ 7066 __ sra(as_Register($dst$$reg), 7067 as_Register($src1$$reg), 7068 as_Register($src2$$reg)); 7069 %} 7070 7071 ins_pipe(ialu_reg_reg_vshift); 7072 %} 7073 7074 // Shift Right Arithmetic Immediate 7075 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 7076 match(Set dst (RShiftL src1 src2)); 7077 7078 ins_cost(ALU_COST); 7079 format %{ "srai $dst, $src1, ($src2 & 0x3f)\t#@rShiftL_reg_imm" %} 7080 7081 ins_encode %{ 7082 // the shift amount is encoded in the lower 7083 // 6 bits of the I-immediate field for RV64I 7084 __ srai(as_Register($dst$$reg), 7085 as_Register($src1$$reg), 7086 (unsigned) $src2$$constant & 0x3f); 7087 %} 7088 7089 ins_pipe(ialu_reg_shift); 7090 %} 7091 7092 instruct regI_not_reg(iRegINoSp dst, iRegI src1, immI_M1 m1) %{ 7093 match(Set dst (XorI src1 m1)); 7094 ins_cost(ALU_COST); 7095 format %{ "xori $dst, $src1, -1\t#@regI_not_reg" %} 7096 7097 ins_encode %{ 7098 __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); 7099 %} 7100 7101 ins_pipe(ialu_reg_imm); 7102 %} 7103 7104 instruct regL_not_reg(iRegLNoSp dst, iRegL src1, immL_M1 m1) %{ 7105 match(Set dst (XorL src1 m1)); 7106 ins_cost(ALU_COST); 7107 format %{ "xori $dst, $src1, -1\t#@regL_not_reg" %} 7108 7109 ins_encode %{ 7110 __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); 7111 %} 7112 7113 ins_pipe(ialu_reg_imm); 7114 %} 7115 7116 7117 // ============================================================================ 7118 // Floating Point Arithmetic Instructions 7119 7120 instruct addF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7121 match(Set dst (AddF src1 src2)); 7122 7123 ins_cost(DEFAULT_COST * 5); 7124 format %{ "fadd.s $dst, $src1, $src2\t#@addF_reg_reg" %} 7125 7126 ins_encode %{ 7127 __ fadd_s(as_FloatRegister($dst$$reg), 7128 as_FloatRegister($src1$$reg), 7129 as_FloatRegister($src2$$reg)); 7130 %} 7131 7132 ins_pipe(fp_dop_reg_reg_s); 7133 %} 7134 7135 instruct addD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7136 match(Set dst (AddD src1 src2)); 7137 7138 ins_cost(DEFAULT_COST * 5); 7139 format %{ "fadd.d $dst, $src1, $src2\t#@addD_reg_reg" %} 7140 7141 ins_encode %{ 7142 __ fadd_d(as_FloatRegister($dst$$reg), 7143 as_FloatRegister($src1$$reg), 7144 as_FloatRegister($src2$$reg)); 7145 %} 7146 7147 ins_pipe(fp_dop_reg_reg_d); 7148 %} 7149 7150 instruct subF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7151 match(Set dst (SubF src1 src2)); 7152 7153 ins_cost(DEFAULT_COST * 5); 7154 format %{ "fsub.s $dst, $src1, $src2\t#@subF_reg_reg" %} 7155 7156 ins_encode %{ 7157 __ fsub_s(as_FloatRegister($dst$$reg), 7158 as_FloatRegister($src1$$reg), 7159 as_FloatRegister($src2$$reg)); 7160 %} 7161 7162 ins_pipe(fp_dop_reg_reg_s); 7163 %} 7164 7165 instruct subD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7166 match(Set dst (SubD src1 src2)); 7167 7168 ins_cost(DEFAULT_COST * 5); 7169 format %{ "fsub.d $dst, $src1, $src2\t#@subD_reg_reg" %} 7170 7171 ins_encode %{ 7172 __ fsub_d(as_FloatRegister($dst$$reg), 7173 as_FloatRegister($src1$$reg), 7174 as_FloatRegister($src2$$reg)); 7175 %} 7176 7177 ins_pipe(fp_dop_reg_reg_d); 7178 %} 7179 7180 instruct mulF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7181 match(Set dst (MulF src1 src2)); 7182 7183 ins_cost(FMUL_SINGLE_COST); 7184 format %{ "fmul.s $dst, $src1, $src2\t#@mulF_reg_reg" %} 7185 7186 ins_encode %{ 7187 __ fmul_s(as_FloatRegister($dst$$reg), 7188 as_FloatRegister($src1$$reg), 7189 as_FloatRegister($src2$$reg)); 7190 %} 7191 7192 ins_pipe(fp_dop_reg_reg_s); 7193 %} 7194 7195 instruct mulD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7196 match(Set dst (MulD src1 src2)); 7197 7198 ins_cost(FMUL_DOUBLE_COST); 7199 format %{ "fmul.d $dst, $src1, $src2\t#@mulD_reg_reg" %} 7200 7201 ins_encode %{ 7202 __ fmul_d(as_FloatRegister($dst$$reg), 7203 as_FloatRegister($src1$$reg), 7204 as_FloatRegister($src2$$reg)); 7205 %} 7206 7207 ins_pipe(fp_dop_reg_reg_d); 7208 %} 7209 7210 // src1 * src2 + src3 7211 instruct maddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7212 match(Set dst (FmaF src3 (Binary src1 src2))); 7213 7214 ins_cost(FMUL_SINGLE_COST); 7215 format %{ "fmadd.s $dst, $src1, $src2, $src3\t#@maddF_reg_reg" %} 7216 7217 ins_encode %{ 7218 assert(UseFMA, "Needs FMA instructions support."); 7219 __ fmadd_s(as_FloatRegister($dst$$reg), 7220 as_FloatRegister($src1$$reg), 7221 as_FloatRegister($src2$$reg), 7222 as_FloatRegister($src3$$reg)); 7223 %} 7224 7225 ins_pipe(pipe_class_default); 7226 %} 7227 7228 // src1 * src2 + src3 7229 instruct maddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7230 match(Set dst (FmaD src3 (Binary src1 src2))); 7231 7232 ins_cost(FMUL_DOUBLE_COST); 7233 format %{ "fmadd.d $dst, $src1, $src2, $src3\t#@maddD_reg_reg" %} 7234 7235 ins_encode %{ 7236 assert(UseFMA, "Needs FMA instructions support."); 7237 __ fmadd_d(as_FloatRegister($dst$$reg), 7238 as_FloatRegister($src1$$reg), 7239 as_FloatRegister($src2$$reg), 7240 as_FloatRegister($src3$$reg)); 7241 %} 7242 7243 ins_pipe(pipe_class_default); 7244 %} 7245 7246 // src1 * src2 - src3 7247 instruct msubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7248 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 7249 7250 ins_cost(FMUL_SINGLE_COST); 7251 format %{ "fmsub.s $dst, $src1, $src2, $src3\t#@msubF_reg_reg" %} 7252 7253 ins_encode %{ 7254 assert(UseFMA, "Needs FMA instructions support."); 7255 __ fmsub_s(as_FloatRegister($dst$$reg), 7256 as_FloatRegister($src1$$reg), 7257 as_FloatRegister($src2$$reg), 7258 as_FloatRegister($src3$$reg)); 7259 %} 7260 7261 ins_pipe(pipe_class_default); 7262 %} 7263 7264 // src1 * src2 - src3 7265 instruct msubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7266 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 7267 7268 ins_cost(FMUL_DOUBLE_COST); 7269 format %{ "fmsub.d $dst, $src1, $src2, $src3\t#@msubD_reg_reg" %} 7270 7271 ins_encode %{ 7272 assert(UseFMA, "Needs FMA instructions support."); 7273 __ fmsub_d(as_FloatRegister($dst$$reg), 7274 as_FloatRegister($src1$$reg), 7275 as_FloatRegister($src2$$reg), 7276 as_FloatRegister($src3$$reg)); 7277 %} 7278 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // src1 * (-src2) + src3 7283 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 7284 instruct nmsubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7285 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 7286 7287 ins_cost(FMUL_SINGLE_COST); 7288 format %{ "fnmsub.s $dst, $src1, $src2, $src3\t#@nmsubF_reg_reg" %} 7289 7290 ins_encode %{ 7291 assert(UseFMA, "Needs FMA instructions support."); 7292 __ fnmsub_s(as_FloatRegister($dst$$reg), 7293 as_FloatRegister($src1$$reg), 7294 as_FloatRegister($src2$$reg), 7295 as_FloatRegister($src3$$reg)); 7296 %} 7297 7298 ins_pipe(pipe_class_default); 7299 %} 7300 7301 // src1 * (-src2) + src3 7302 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 7303 instruct nmsubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7304 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 7305 7306 ins_cost(FMUL_DOUBLE_COST); 7307 format %{ "fnmsub.d $dst, $src1, $src2, $src3\t#@nmsubD_reg_reg" %} 7308 7309 ins_encode %{ 7310 assert(UseFMA, "Needs FMA instructions support."); 7311 __ fnmsub_d(as_FloatRegister($dst$$reg), 7312 as_FloatRegister($src1$$reg), 7313 as_FloatRegister($src2$$reg), 7314 as_FloatRegister($src3$$reg)); 7315 %} 7316 7317 ins_pipe(pipe_class_default); 7318 %} 7319 7320 // src1 * (-src2) - src3 7321 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 7322 instruct nmaddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7323 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 7324 7325 ins_cost(FMUL_SINGLE_COST); 7326 format %{ "fnmadd.s $dst, $src1, $src2, $src3\t#@nmaddF_reg_reg" %} 7327 7328 ins_encode %{ 7329 assert(UseFMA, "Needs FMA instructions support."); 7330 __ fnmadd_s(as_FloatRegister($dst$$reg), 7331 as_FloatRegister($src1$$reg), 7332 as_FloatRegister($src2$$reg), 7333 as_FloatRegister($src3$$reg)); 7334 %} 7335 7336 ins_pipe(pipe_class_default); 7337 %} 7338 7339 // src1 * (-src2) - src3 7340 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 7341 instruct nmaddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7342 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 7343 7344 ins_cost(FMUL_DOUBLE_COST); 7345 format %{ "fnmadd.d $dst, $src1, $src2, $src3\t#@nmaddD_reg_reg" %} 7346 7347 ins_encode %{ 7348 assert(UseFMA, "Needs FMA instructions support."); 7349 __ fnmadd_d(as_FloatRegister($dst$$reg), 7350 as_FloatRegister($src1$$reg), 7351 as_FloatRegister($src2$$reg), 7352 as_FloatRegister($src3$$reg)); 7353 %} 7354 7355 ins_pipe(pipe_class_default); 7356 %} 7357 7358 // Math.max(FF)F 7359 instruct maxF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ 7360 match(Set dst (MaxF src1 src2)); 7361 effect(TEMP_DEF dst, KILL cr); 7362 7363 format %{ "maxF $dst, $src1, $src2" %} 7364 7365 ins_encode %{ 7366 __ minmax_fp(as_FloatRegister($dst$$reg), 7367 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7368 false /* is_double */, false /* is_min */); 7369 %} 7370 7371 ins_pipe(pipe_class_default); 7372 %} 7373 7374 // Math.min(FF)F 7375 instruct minF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ 7376 match(Set dst (MinF src1 src2)); 7377 effect(TEMP_DEF dst, KILL cr); 7378 7379 format %{ "minF $dst, $src1, $src2" %} 7380 7381 ins_encode %{ 7382 __ minmax_fp(as_FloatRegister($dst$$reg), 7383 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7384 false /* is_double */, true /* is_min */); 7385 %} 7386 7387 ins_pipe(pipe_class_default); 7388 %} 7389 7390 // Math.max(DD)D 7391 instruct maxD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ 7392 match(Set dst (MaxD src1 src2)); 7393 effect(TEMP_DEF dst, KILL cr); 7394 7395 format %{ "maxD $dst, $src1, $src2" %} 7396 7397 ins_encode %{ 7398 __ minmax_fp(as_FloatRegister($dst$$reg), 7399 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7400 true /* is_double */, false /* is_min */); 7401 %} 7402 7403 ins_pipe(pipe_class_default); 7404 %} 7405 7406 // Math.min(DD)D 7407 instruct minD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ 7408 match(Set dst (MinD src1 src2)); 7409 effect(TEMP_DEF dst, KILL cr); 7410 7411 format %{ "minD $dst, $src1, $src2" %} 7412 7413 ins_encode %{ 7414 __ minmax_fp(as_FloatRegister($dst$$reg), 7415 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7416 true /* is_double */, true /* is_min */); 7417 %} 7418 7419 ins_pipe(pipe_class_default); 7420 %} 7421 7422 // Float.isInfinite 7423 instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src) 7424 %{ 7425 match(Set dst (IsInfiniteF src)); 7426 7427 format %{ "isInfinite $dst, $src" %} 7428 ins_encode %{ 7429 __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7430 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf); 7431 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7432 %} 7433 7434 ins_pipe(pipe_class_default); 7435 %} 7436 7437 // Double.isInfinite 7438 instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src) 7439 %{ 7440 match(Set dst (IsInfiniteD src)); 7441 7442 format %{ "isInfinite $dst, $src" %} 7443 ins_encode %{ 7444 __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7445 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf); 7446 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7447 %} 7448 7449 ins_pipe(pipe_class_default); 7450 %} 7451 7452 // Float.isFinite 7453 instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src) 7454 %{ 7455 match(Set dst (IsFiniteF src)); 7456 7457 format %{ "isFinite $dst, $src" %} 7458 ins_encode %{ 7459 __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7460 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite); 7461 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7462 %} 7463 7464 ins_pipe(pipe_class_default); 7465 %} 7466 7467 // Double.isFinite 7468 instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src) 7469 %{ 7470 match(Set dst (IsFiniteD src)); 7471 7472 format %{ "isFinite $dst, $src" %} 7473 ins_encode %{ 7474 __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7475 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite); 7476 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7477 %} 7478 7479 ins_pipe(pipe_class_default); 7480 %} 7481 7482 instruct divF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7483 match(Set dst (DivF src1 src2)); 7484 7485 ins_cost(FDIV_COST); 7486 format %{ "fdiv.s $dst, $src1, $src2\t#@divF_reg_reg" %} 7487 7488 ins_encode %{ 7489 __ fdiv_s(as_FloatRegister($dst$$reg), 7490 as_FloatRegister($src1$$reg), 7491 as_FloatRegister($src2$$reg)); 7492 %} 7493 7494 ins_pipe(fp_div_s); 7495 %} 7496 7497 instruct divD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7498 match(Set dst (DivD src1 src2)); 7499 7500 ins_cost(FDIV_COST); 7501 format %{ "fdiv.d $dst, $src1, $src2\t#@divD_reg_reg" %} 7502 7503 ins_encode %{ 7504 __ fdiv_d(as_FloatRegister($dst$$reg), 7505 as_FloatRegister($src1$$reg), 7506 as_FloatRegister($src2$$reg)); 7507 %} 7508 7509 ins_pipe(fp_div_d); 7510 %} 7511 7512 instruct negF_reg_reg(fRegF dst, fRegF src) %{ 7513 match(Set dst (NegF src)); 7514 7515 ins_cost(XFER_COST); 7516 format %{ "fsgnjn.s $dst, $src, $src\t#@negF_reg_reg" %} 7517 7518 ins_encode %{ 7519 __ fneg_s(as_FloatRegister($dst$$reg), 7520 as_FloatRegister($src$$reg)); 7521 %} 7522 7523 ins_pipe(fp_uop_s); 7524 %} 7525 7526 instruct negD_reg_reg(fRegD dst, fRegD src) %{ 7527 match(Set dst (NegD src)); 7528 7529 ins_cost(XFER_COST); 7530 format %{ "fsgnjn.d $dst, $src, $src\t#@negD_reg_reg" %} 7531 7532 ins_encode %{ 7533 __ fneg_d(as_FloatRegister($dst$$reg), 7534 as_FloatRegister($src$$reg)); 7535 %} 7536 7537 ins_pipe(fp_uop_d); 7538 %} 7539 7540 instruct absI_reg(iRegINoSp dst, iRegIorL2I src) %{ 7541 match(Set dst (AbsI src)); 7542 7543 ins_cost(ALU_COST * 3); 7544 format %{ 7545 "sraiw t0, $src, 0x1f\n\t" 7546 "addw $dst, $src, t0\n\t" 7547 "xorr $dst, $dst, t0\t#@absI_reg" 7548 %} 7549 7550 ins_encode %{ 7551 __ sraiw(t0, as_Register($src$$reg), 0x1f); 7552 __ addw(as_Register($dst$$reg), as_Register($src$$reg), t0); 7553 __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); 7554 %} 7555 7556 ins_pipe(pipe_class_default); 7557 %} 7558 7559 instruct absL_reg(iRegLNoSp dst, iRegL src) %{ 7560 match(Set dst (AbsL src)); 7561 7562 ins_cost(ALU_COST * 3); 7563 format %{ 7564 "srai t0, $src, 0x3f\n\t" 7565 "add $dst, $src, t0\n\t" 7566 "xorr $dst, $dst, t0\t#@absL_reg" 7567 %} 7568 7569 ins_encode %{ 7570 __ srai(t0, as_Register($src$$reg), 0x3f); 7571 __ add(as_Register($dst$$reg), as_Register($src$$reg), t0); 7572 __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); 7573 %} 7574 7575 ins_pipe(pipe_class_default); 7576 %} 7577 7578 instruct absF_reg(fRegF dst, fRegF src) %{ 7579 match(Set dst (AbsF src)); 7580 7581 ins_cost(XFER_COST); 7582 format %{ "fsgnjx.s $dst, $src, $src\t#@absF_reg" %} 7583 ins_encode %{ 7584 __ fabs_s(as_FloatRegister($dst$$reg), 7585 as_FloatRegister($src$$reg)); 7586 %} 7587 7588 ins_pipe(fp_uop_s); 7589 %} 7590 7591 instruct absD_reg(fRegD dst, fRegD src) %{ 7592 match(Set dst (AbsD src)); 7593 7594 ins_cost(XFER_COST); 7595 format %{ "fsgnjx.d $dst, $src, $src\t#@absD_reg" %} 7596 ins_encode %{ 7597 __ fabs_d(as_FloatRegister($dst$$reg), 7598 as_FloatRegister($src$$reg)); 7599 %} 7600 7601 ins_pipe(fp_uop_d); 7602 %} 7603 7604 instruct sqrtF_reg(fRegF dst, fRegF src) %{ 7605 match(Set dst (SqrtF src)); 7606 7607 ins_cost(FSQRT_COST); 7608 format %{ "fsqrt.s $dst, $src\t#@sqrtF_reg" %} 7609 ins_encode %{ 7610 __ fsqrt_s(as_FloatRegister($dst$$reg), 7611 as_FloatRegister($src$$reg)); 7612 %} 7613 7614 ins_pipe(fp_sqrt_s); 7615 %} 7616 7617 instruct sqrtD_reg(fRegD dst, fRegD src) %{ 7618 match(Set dst (SqrtD src)); 7619 7620 ins_cost(FSQRT_COST); 7621 format %{ "fsqrt.d $dst, $src\t#@sqrtD_reg" %} 7622 ins_encode %{ 7623 __ fsqrt_d(as_FloatRegister($dst$$reg), 7624 as_FloatRegister($src$$reg)); 7625 %} 7626 7627 ins_pipe(fp_sqrt_d); 7628 %} 7629 7630 // Round Instruction 7631 instruct roundD_reg(fRegD dst, fRegD src, immI rmode, iRegLNoSp tmp1, iRegLNoSp tmp2, iRegLNoSp tmp3) %{ 7632 match(Set dst (RoundDoubleMode src rmode)); 7633 ins_cost(2 * XFER_COST + BRANCH_COST); 7634 effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3); 7635 7636 format %{ "RoundDoubleMode $src, $rmode" %} 7637 ins_encode %{ 7638 __ round_double_mode(as_FloatRegister($dst$$reg), 7639 as_FloatRegister($src$$reg), $rmode$$constant, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 7640 %} 7641 ins_pipe(pipe_class_default); 7642 %} 7643 7644 // Copysign and signum intrinsics 7645 7646 instruct copySignD_reg(fRegD dst, fRegD src1, fRegD src2, immD zero) %{ 7647 match(Set dst (CopySignD src1 (Binary src2 zero))); 7648 format %{ "CopySignD $dst $src1 $src2" %} 7649 ins_encode %{ 7650 FloatRegister dst = as_FloatRegister($dst$$reg), 7651 src1 = as_FloatRegister($src1$$reg), 7652 src2 = as_FloatRegister($src2$$reg); 7653 __ fsgnj_d(dst, src1, src2); 7654 %} 7655 ins_pipe(fp_dop_reg_reg_d); 7656 %} 7657 7658 instruct copySignF_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7659 match(Set dst (CopySignF src1 src2)); 7660 format %{ "CopySignF $dst $src1 $src2" %} 7661 ins_encode %{ 7662 FloatRegister dst = as_FloatRegister($dst$$reg), 7663 src1 = as_FloatRegister($src1$$reg), 7664 src2 = as_FloatRegister($src2$$reg); 7665 __ fsgnj_s(dst, src1, src2); 7666 %} 7667 ins_pipe(fp_dop_reg_reg_s); 7668 %} 7669 7670 instruct signumD_reg(fRegD dst, immD zero, fRegD one) %{ 7671 match(Set dst (SignumD dst (Binary zero one))); 7672 format %{ "signumD $dst, $dst" %} 7673 ins_encode %{ 7674 __ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($one$$reg), true /* is_double */); 7675 %} 7676 ins_pipe(pipe_class_default); 7677 %} 7678 7679 instruct signumF_reg(fRegF dst, immF zero, fRegF one) %{ 7680 match(Set dst (SignumF dst (Binary zero one))); 7681 format %{ "signumF $dst, $dst" %} 7682 ins_encode %{ 7683 __ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($one$$reg), false /* is_double */); 7684 %} 7685 ins_pipe(pipe_class_default); 7686 %} 7687 7688 // Arithmetic Instructions End 7689 7690 // ============================================================================ 7691 // Logical Instructions 7692 7693 // Register And 7694 instruct andI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7695 match(Set dst (AndI src1 src2)); 7696 7697 format %{ "andr $dst, $src1, $src2\t#@andI_reg_reg" %} 7698 7699 ins_cost(ALU_COST); 7700 ins_encode %{ 7701 __ andr(as_Register($dst$$reg), 7702 as_Register($src1$$reg), 7703 as_Register($src2$$reg)); 7704 %} 7705 7706 ins_pipe(ialu_reg_reg); 7707 %} 7708 7709 // Immediate And 7710 instruct andI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7711 match(Set dst (AndI src1 src2)); 7712 7713 format %{ "andi $dst, $src1, $src2\t#@andI_reg_imm" %} 7714 7715 ins_cost(ALU_COST); 7716 ins_encode %{ 7717 __ andi(as_Register($dst$$reg), 7718 as_Register($src1$$reg), 7719 (int32_t)($src2$$constant)); 7720 %} 7721 7722 ins_pipe(ialu_reg_imm); 7723 %} 7724 7725 // Register Or 7726 instruct orI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7727 match(Set dst (OrI src1 src2)); 7728 7729 format %{ "orr $dst, $src1, $src2\t#@orI_reg_reg" %} 7730 7731 ins_cost(ALU_COST); 7732 ins_encode %{ 7733 __ orr(as_Register($dst$$reg), 7734 as_Register($src1$$reg), 7735 as_Register($src2$$reg)); 7736 %} 7737 7738 ins_pipe(ialu_reg_reg); 7739 %} 7740 7741 // Immediate Or 7742 instruct orI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7743 match(Set dst (OrI src1 src2)); 7744 7745 format %{ "ori $dst, $src1, $src2\t#@orI_reg_imm" %} 7746 7747 ins_cost(ALU_COST); 7748 ins_encode %{ 7749 __ ori(as_Register($dst$$reg), 7750 as_Register($src1$$reg), 7751 (int32_t)($src2$$constant)); 7752 %} 7753 7754 ins_pipe(ialu_reg_imm); 7755 %} 7756 7757 // Register Xor 7758 instruct xorI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7759 match(Set dst (XorI src1 src2)); 7760 7761 format %{ "xorr $dst, $src1, $src2\t#@xorI_reg_reg" %} 7762 7763 ins_cost(ALU_COST); 7764 ins_encode %{ 7765 __ xorr(as_Register($dst$$reg), 7766 as_Register($src1$$reg), 7767 as_Register($src2$$reg)); 7768 %} 7769 7770 ins_pipe(ialu_reg_reg); 7771 %} 7772 7773 // Immediate Xor 7774 instruct xorI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7775 match(Set dst (XorI src1 src2)); 7776 7777 format %{ "xori $dst, $src1, $src2\t#@xorI_reg_imm" %} 7778 7779 ins_cost(ALU_COST); 7780 ins_encode %{ 7781 __ xori(as_Register($dst$$reg), 7782 as_Register($src1$$reg), 7783 (int32_t)($src2$$constant)); 7784 %} 7785 7786 ins_pipe(ialu_reg_imm); 7787 %} 7788 7789 // Register And Long 7790 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7791 match(Set dst (AndL src1 src2)); 7792 7793 format %{ "andr $dst, $src1, $src2\t#@andL_reg_reg" %} 7794 7795 ins_cost(ALU_COST); 7796 ins_encode %{ 7797 __ andr(as_Register($dst$$reg), 7798 as_Register($src1$$reg), 7799 as_Register($src2$$reg)); 7800 %} 7801 7802 ins_pipe(ialu_reg_reg); 7803 %} 7804 7805 // Immediate And Long 7806 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7807 match(Set dst (AndL src1 src2)); 7808 7809 format %{ "andi $dst, $src1, $src2\t#@andL_reg_imm" %} 7810 7811 ins_cost(ALU_COST); 7812 ins_encode %{ 7813 __ andi(as_Register($dst$$reg), 7814 as_Register($src1$$reg), 7815 (int32_t)($src2$$constant)); 7816 %} 7817 7818 ins_pipe(ialu_reg_imm); 7819 %} 7820 7821 // Register Or Long 7822 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7823 match(Set dst (OrL src1 src2)); 7824 7825 format %{ "orr $dst, $src1, $src2\t#@orL_reg_reg" %} 7826 7827 ins_cost(ALU_COST); 7828 ins_encode %{ 7829 __ orr(as_Register($dst$$reg), 7830 as_Register($src1$$reg), 7831 as_Register($src2$$reg)); 7832 %} 7833 7834 ins_pipe(ialu_reg_reg); 7835 %} 7836 7837 // Immediate Or Long 7838 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7839 match(Set dst (OrL src1 src2)); 7840 7841 format %{ "ori $dst, $src1, $src2\t#@orL_reg_imm" %} 7842 7843 ins_cost(ALU_COST); 7844 ins_encode %{ 7845 __ ori(as_Register($dst$$reg), 7846 as_Register($src1$$reg), 7847 (int32_t)($src2$$constant)); 7848 %} 7849 7850 ins_pipe(ialu_reg_imm); 7851 %} 7852 7853 // Register Xor Long 7854 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7855 match(Set dst (XorL src1 src2)); 7856 7857 format %{ "xorr $dst, $src1, $src2\t#@xorL_reg_reg" %} 7858 7859 ins_cost(ALU_COST); 7860 ins_encode %{ 7861 __ xorr(as_Register($dst$$reg), 7862 as_Register($src1$$reg), 7863 as_Register($src2$$reg)); 7864 %} 7865 7866 ins_pipe(ialu_reg_reg); 7867 %} 7868 7869 // Immediate Xor Long 7870 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7871 match(Set dst (XorL src1 src2)); 7872 7873 ins_cost(ALU_COST); 7874 format %{ "xori $dst, $src1, $src2\t#@xorL_reg_imm" %} 7875 7876 ins_encode %{ 7877 __ xori(as_Register($dst$$reg), 7878 as_Register($src1$$reg), 7879 (int32_t)($src2$$constant)); 7880 %} 7881 7882 ins_pipe(ialu_reg_imm); 7883 %} 7884 7885 // ============================================================================ 7886 // MemBar Instruction 7887 7888 instruct load_fence() %{ 7889 match(LoadFence); 7890 ins_cost(ALU_COST); 7891 7892 format %{ "#@load_fence" %} 7893 7894 ins_encode %{ 7895 __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); 7896 %} 7897 ins_pipe(pipe_serial); 7898 %} 7899 7900 instruct membar_acquire() %{ 7901 match(MemBarAcquire); 7902 ins_cost(ALU_COST); 7903 7904 format %{ "#@membar_acquire\n\t" 7905 "fence ir iorw" %} 7906 7907 ins_encode %{ 7908 __ block_comment("membar_acquire"); 7909 __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); 7910 %} 7911 7912 ins_pipe(pipe_serial); 7913 %} 7914 7915 instruct membar_acquire_lock() %{ 7916 match(MemBarAcquireLock); 7917 ins_cost(0); 7918 7919 format %{ "#@membar_acquire_lock (elided)" %} 7920 7921 ins_encode %{ 7922 __ block_comment("membar_acquire_lock (elided)"); 7923 %} 7924 7925 ins_pipe(pipe_serial); 7926 %} 7927 7928 instruct store_fence() %{ 7929 match(StoreFence); 7930 ins_cost(ALU_COST); 7931 7932 format %{ "#@store_fence" %} 7933 7934 ins_encode %{ 7935 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 7936 %} 7937 ins_pipe(pipe_serial); 7938 %} 7939 7940 instruct membar_release() %{ 7941 match(MemBarRelease); 7942 ins_cost(ALU_COST); 7943 7944 format %{ "#@membar_release\n\t" 7945 "fence iorw ow" %} 7946 7947 ins_encode %{ 7948 __ block_comment("membar_release"); 7949 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 7950 %} 7951 ins_pipe(pipe_serial); 7952 %} 7953 7954 instruct membar_storestore() %{ 7955 match(MemBarStoreStore); 7956 match(StoreStoreFence); 7957 ins_cost(ALU_COST); 7958 7959 format %{ "MEMBAR-store-store\t#@membar_storestore" %} 7960 7961 ins_encode %{ 7962 __ membar(MacroAssembler::StoreStore); 7963 %} 7964 ins_pipe(pipe_serial); 7965 %} 7966 7967 instruct membar_release_lock() %{ 7968 match(MemBarReleaseLock); 7969 ins_cost(0); 7970 7971 format %{ "#@membar_release_lock (elided)" %} 7972 7973 ins_encode %{ 7974 __ block_comment("membar_release_lock (elided)"); 7975 %} 7976 7977 ins_pipe(pipe_serial); 7978 %} 7979 7980 instruct membar_volatile() %{ 7981 match(MemBarVolatile); 7982 ins_cost(ALU_COST); 7983 7984 format %{ "#@membar_volatile\n\t" 7985 "fence iorw iorw"%} 7986 7987 ins_encode %{ 7988 __ block_comment("membar_volatile"); 7989 __ membar(MacroAssembler::StoreLoad); 7990 %} 7991 7992 ins_pipe(pipe_serial); 7993 %} 7994 7995 instruct spin_wait() %{ 7996 predicate(UseZihintpause); 7997 match(OnSpinWait); 7998 ins_cost(CACHE_MISS_COST); 7999 8000 format %{ "spin_wait" %} 8001 8002 ins_encode %{ 8003 __ pause(); 8004 %} 8005 8006 ins_pipe(pipe_serial); 8007 %} 8008 8009 // ============================================================================ 8010 // Cast Instructions (Java-level type cast) 8011 8012 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8013 match(Set dst (CastX2P src)); 8014 8015 ins_cost(ALU_COST); 8016 format %{ "mv $dst, $src\t# long -> ptr, #@castX2P" %} 8017 8018 ins_encode %{ 8019 if ($dst$$reg != $src$$reg) { 8020 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8021 } 8022 %} 8023 8024 ins_pipe(ialu_reg); 8025 %} 8026 8027 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8028 match(Set dst (CastP2X src)); 8029 8030 ins_cost(ALU_COST); 8031 format %{ "mv $dst, $src\t# ptr -> long, #@castP2X" %} 8032 8033 ins_encode %{ 8034 if ($dst$$reg != $src$$reg) { 8035 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8036 } 8037 %} 8038 8039 ins_pipe(ialu_reg); 8040 %} 8041 8042 instruct castPP(iRegPNoSp dst) 8043 %{ 8044 match(Set dst (CastPP dst)); 8045 ins_cost(0); 8046 8047 size(0); 8048 format %{ "# castPP of $dst, #@castPP" %} 8049 ins_encode(/* empty encoding */); 8050 ins_pipe(pipe_class_empty); 8051 %} 8052 8053 instruct castLL(iRegL dst) 8054 %{ 8055 match(Set dst (CastLL dst)); 8056 8057 size(0); 8058 format %{ "# castLL of $dst, #@castLL" %} 8059 ins_encode(/* empty encoding */); 8060 ins_cost(0); 8061 ins_pipe(pipe_class_empty); 8062 %} 8063 8064 instruct castII(iRegI dst) 8065 %{ 8066 match(Set dst (CastII dst)); 8067 8068 size(0); 8069 format %{ "# castII of $dst, #@castII" %} 8070 ins_encode(/* empty encoding */); 8071 ins_cost(0); 8072 ins_pipe(pipe_class_empty); 8073 %} 8074 8075 instruct checkCastPP(iRegPNoSp dst) 8076 %{ 8077 match(Set dst (CheckCastPP dst)); 8078 8079 size(0); 8080 ins_cost(0); 8081 format %{ "# checkcastPP of $dst, #@checkCastPP" %} 8082 ins_encode(/* empty encoding */); 8083 ins_pipe(pipe_class_empty); 8084 %} 8085 8086 instruct castFF(fRegF dst) 8087 %{ 8088 match(Set dst (CastFF dst)); 8089 8090 size(0); 8091 format %{ "# castFF of $dst" %} 8092 ins_encode(/* empty encoding */); 8093 ins_cost(0); 8094 ins_pipe(pipe_class_empty); 8095 %} 8096 8097 instruct castDD(fRegD dst) 8098 %{ 8099 match(Set dst (CastDD dst)); 8100 8101 size(0); 8102 format %{ "# castDD of $dst" %} 8103 ins_encode(/* empty encoding */); 8104 ins_cost(0); 8105 ins_pipe(pipe_class_empty); 8106 %} 8107 8108 instruct castVV(vReg dst) 8109 %{ 8110 match(Set dst (CastVV dst)); 8111 8112 size(0); 8113 format %{ "# castVV of $dst" %} 8114 ins_encode(/* empty encoding */); 8115 ins_cost(0); 8116 ins_pipe(pipe_class_empty); 8117 %} 8118 8119 // ============================================================================ 8120 // Convert Instructions 8121 8122 // int to bool 8123 instruct convI2Bool(iRegINoSp dst, iRegI src) 8124 %{ 8125 match(Set dst (Conv2B src)); 8126 8127 ins_cost(ALU_COST); 8128 format %{ "snez $dst, $src\t#@convI2Bool" %} 8129 8130 ins_encode %{ 8131 __ snez(as_Register($dst$$reg), as_Register($src$$reg)); 8132 %} 8133 8134 ins_pipe(ialu_reg); 8135 %} 8136 8137 // pointer to bool 8138 instruct convP2Bool(iRegINoSp dst, iRegP src) 8139 %{ 8140 match(Set dst (Conv2B src)); 8141 8142 ins_cost(ALU_COST); 8143 format %{ "snez $dst, $src\t#@convP2Bool" %} 8144 8145 ins_encode %{ 8146 __ snez(as_Register($dst$$reg), as_Register($src$$reg)); 8147 %} 8148 8149 ins_pipe(ialu_reg); 8150 %} 8151 8152 // int <-> long 8153 8154 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 8155 %{ 8156 match(Set dst (ConvI2L src)); 8157 8158 ins_cost(ALU_COST); 8159 format %{ "addw $dst, $src, zr\t#@convI2L_reg_reg" %} 8160 ins_encode %{ 8161 __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8162 %} 8163 ins_pipe(ialu_reg); 8164 %} 8165 8166 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 8167 match(Set dst (ConvL2I src)); 8168 8169 ins_cost(ALU_COST); 8170 format %{ "addw $dst, $src, zr\t#@convL2I_reg" %} 8171 8172 ins_encode %{ 8173 __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8174 %} 8175 8176 ins_pipe(ialu_reg); 8177 %} 8178 8179 // int to unsigned long (Zero-extend) 8180 instruct convI2UL_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 8181 %{ 8182 match(Set dst (AndL (ConvI2L src) mask)); 8183 8184 ins_cost(ALU_COST * 2); 8185 format %{ "zero_extend $dst, $src, 32\t# i2ul, #@convI2UL_reg_reg" %} 8186 8187 ins_encode %{ 8188 __ zero_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8189 %} 8190 8191 ins_pipe(ialu_reg_shift); 8192 %} 8193 8194 // float <-> double 8195 8196 instruct convF2D_reg(fRegD dst, fRegF src) %{ 8197 match(Set dst (ConvF2D src)); 8198 8199 ins_cost(XFER_COST); 8200 format %{ "fcvt.d.s $dst, $src\t#@convF2D_reg" %} 8201 8202 ins_encode %{ 8203 __ fcvt_d_s(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 8204 %} 8205 8206 ins_pipe(fp_f2d); 8207 %} 8208 8209 instruct convD2F_reg(fRegF dst, fRegD src) %{ 8210 match(Set dst (ConvD2F src)); 8211 8212 ins_cost(XFER_COST); 8213 format %{ "fcvt.s.d $dst, $src\t#@convD2F_reg" %} 8214 8215 ins_encode %{ 8216 __ fcvt_s_d(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 8217 %} 8218 8219 ins_pipe(fp_d2f); 8220 %} 8221 8222 // single <-> half precision 8223 8224 instruct convHF2F_reg_reg(fRegF dst, iRegINoSp src, iRegINoSp tmp) %{ 8225 match(Set dst (ConvHF2F src)); 8226 effect(TEMP tmp); 8227 format %{ "fmv.h.x $dst, $src\t# move source from $src to $dst\n\t" 8228 "fcvt.s.h $dst, $dst\t# convert half to single precision" 8229 %} 8230 ins_encode %{ 8231 __ float16_to_float($dst$$FloatRegister, $src$$Register, $tmp$$Register); 8232 %} 8233 ins_pipe(pipe_slow); 8234 %} 8235 8236 instruct convF2HF_reg_reg(iRegINoSp dst, fRegF src, fRegF ftmp, iRegINoSp xtmp) %{ 8237 match(Set dst (ConvF2HF src)); 8238 effect(TEMP_DEF dst, TEMP ftmp, TEMP xtmp); 8239 format %{ "fcvt.h.s $ftmp, $src\t# convert single precision to half\n\t" 8240 "fmv.x.h $dst, $ftmp\t# move result from $ftmp to $dst" 8241 %} 8242 ins_encode %{ 8243 __ float_to_float16($dst$$Register, $src$$FloatRegister, $ftmp$$FloatRegister, $xtmp$$Register); 8244 %} 8245 ins_pipe(pipe_slow); 8246 %} 8247 8248 // float <-> int 8249 8250 instruct convF2I_reg_reg(iRegINoSp dst, fRegF src) %{ 8251 match(Set dst (ConvF2I src)); 8252 8253 ins_cost(XFER_COST); 8254 format %{ "fcvt.w.s $dst, $src\t#@convF2I_reg_reg" %} 8255 8256 ins_encode %{ 8257 __ fcvt_w_s_safe($dst$$Register, $src$$FloatRegister); 8258 %} 8259 8260 ins_pipe(fp_f2i); 8261 %} 8262 8263 instruct convI2F_reg_reg(fRegF dst, iRegIorL2I src) %{ 8264 match(Set dst (ConvI2F src)); 8265 8266 ins_cost(XFER_COST); 8267 format %{ "fcvt.s.w $dst, $src\t#@convI2F_reg_reg" %} 8268 8269 ins_encode %{ 8270 __ fcvt_s_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8271 %} 8272 8273 ins_pipe(fp_i2f); 8274 %} 8275 8276 // float <-> long 8277 8278 instruct convF2L_reg_reg(iRegLNoSp dst, fRegF src) %{ 8279 match(Set dst (ConvF2L src)); 8280 8281 ins_cost(XFER_COST); 8282 format %{ "fcvt.l.s $dst, $src\t#@convF2L_reg_reg" %} 8283 8284 ins_encode %{ 8285 __ fcvt_l_s_safe($dst$$Register, $src$$FloatRegister); 8286 %} 8287 8288 ins_pipe(fp_f2l); 8289 %} 8290 8291 instruct convL2F_reg_reg(fRegF dst, iRegL src) %{ 8292 match(Set dst (ConvL2F src)); 8293 8294 ins_cost(XFER_COST); 8295 format %{ "fcvt.s.l $dst, $src\t#@convL2F_reg_reg" %} 8296 8297 ins_encode %{ 8298 __ fcvt_s_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8299 %} 8300 8301 ins_pipe(fp_l2f); 8302 %} 8303 8304 // double <-> int 8305 8306 instruct convD2I_reg_reg(iRegINoSp dst, fRegD src) %{ 8307 match(Set dst (ConvD2I src)); 8308 8309 ins_cost(XFER_COST); 8310 format %{ "fcvt.w.d $dst, $src\t#@convD2I_reg_reg" %} 8311 8312 ins_encode %{ 8313 __ fcvt_w_d_safe($dst$$Register, $src$$FloatRegister); 8314 %} 8315 8316 ins_pipe(fp_d2i); 8317 %} 8318 8319 instruct convI2D_reg_reg(fRegD dst, iRegIorL2I src) %{ 8320 match(Set dst (ConvI2D src)); 8321 8322 ins_cost(XFER_COST); 8323 format %{ "fcvt.d.w $dst, $src\t#@convI2D_reg_reg" %} 8324 8325 ins_encode %{ 8326 __ fcvt_d_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8327 %} 8328 8329 ins_pipe(fp_i2d); 8330 %} 8331 8332 // double <-> long 8333 8334 instruct convD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ 8335 match(Set dst (ConvD2L src)); 8336 8337 ins_cost(XFER_COST); 8338 format %{ "fcvt.l.d $dst, $src\t#@convD2L_reg_reg" %} 8339 8340 ins_encode %{ 8341 __ fcvt_l_d_safe($dst$$Register, $src$$FloatRegister); 8342 %} 8343 8344 ins_pipe(fp_d2l); 8345 %} 8346 8347 instruct convL2D_reg_reg(fRegD dst, iRegL src) %{ 8348 match(Set dst (ConvL2D src)); 8349 8350 ins_cost(XFER_COST); 8351 format %{ "fcvt.d.l $dst, $src\t#@convL2D_reg_reg" %} 8352 8353 ins_encode %{ 8354 __ fcvt_d_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8355 %} 8356 8357 ins_pipe(fp_l2d); 8358 %} 8359 8360 // Convert oop into int for vectors alignment masking 8361 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8362 match(Set dst (ConvL2I (CastP2X src))); 8363 8364 ins_cost(ALU_COST * 2); 8365 format %{ "zero_extend $dst, $src, 32\t# ptr -> int, #@convP2I" %} 8366 8367 ins_encode %{ 8368 __ zero_extend($dst$$Register, $src$$Register, 32); 8369 %} 8370 8371 ins_pipe(ialu_reg); 8372 %} 8373 8374 // Convert compressed oop into int for vectors alignment masking 8375 // in case of 32bit oops (heap < 4Gb). 8376 instruct convN2I(iRegINoSp dst, iRegN src) 8377 %{ 8378 predicate(CompressedOops::shift() == 0); 8379 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8380 8381 ins_cost(ALU_COST); 8382 format %{ "mv $dst, $src\t# compressed ptr -> int, #@convN2I" %} 8383 8384 ins_encode %{ 8385 __ mv($dst$$Register, $src$$Register); 8386 %} 8387 8388 ins_pipe(ialu_reg); 8389 %} 8390 8391 instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{ 8392 match(Set dst (RoundD src)); 8393 8394 ins_cost(XFER_COST + BRANCH_COST); 8395 effect(TEMP ftmp); 8396 format %{ "java_round_double $dst, $src\t#@round_double_reg" %} 8397 8398 ins_encode %{ 8399 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg)); 8400 %} 8401 8402 ins_pipe(pipe_slow); 8403 %} 8404 8405 instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{ 8406 match(Set dst (RoundF src)); 8407 8408 ins_cost(XFER_COST + BRANCH_COST); 8409 effect(TEMP ftmp); 8410 format %{ "java_round_float $dst, $src\t#@round_float_reg" %} 8411 8412 ins_encode %{ 8413 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg)); 8414 %} 8415 8416 ins_pipe(pipe_slow); 8417 %} 8418 8419 // Convert oop pointer into compressed form 8420 instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{ 8421 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8422 match(Set dst (EncodeP src)); 8423 ins_cost(ALU_COST); 8424 format %{ "encode_heap_oop $dst, $src\t#@encodeHeapOop" %} 8425 ins_encode %{ 8426 Register s = $src$$Register; 8427 Register d = $dst$$Register; 8428 __ encode_heap_oop(d, s); 8429 %} 8430 ins_pipe(pipe_class_default); 8431 %} 8432 8433 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src) %{ 8434 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8435 match(Set dst (EncodeP src)); 8436 ins_cost(ALU_COST); 8437 format %{ "encode_heap_oop_not_null $dst, $src\t#@encodeHeapOop_not_null" %} 8438 ins_encode %{ 8439 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8440 %} 8441 ins_pipe(pipe_class_default); 8442 %} 8443 8444 instruct decodeHeapOop(iRegPNoSp dst, iRegN src) %{ 8445 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8446 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8447 match(Set dst (DecodeN src)); 8448 8449 ins_cost(0); 8450 format %{ "decode_heap_oop $dst, $src\t#@decodeHeapOop" %} 8451 ins_encode %{ 8452 Register s = $src$$Register; 8453 Register d = $dst$$Register; 8454 __ decode_heap_oop(d, s); 8455 %} 8456 ins_pipe(pipe_class_default); 8457 %} 8458 8459 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src) %{ 8460 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8461 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8462 match(Set dst (DecodeN src)); 8463 8464 ins_cost(0); 8465 format %{ "decode_heap_oop_not_null $dst, $src\t#@decodeHeapOop_not_null" %} 8466 ins_encode %{ 8467 Register s = $src$$Register; 8468 Register d = $dst$$Register; 8469 __ decode_heap_oop_not_null(d, s); 8470 %} 8471 ins_pipe(pipe_class_default); 8472 %} 8473 8474 // Convert klass pointer into compressed form. 8475 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8476 match(Set dst (EncodePKlass src)); 8477 8478 ins_cost(ALU_COST); 8479 format %{ "encode_klass_not_null $dst, $src\t#@encodeKlass_not_null" %} 8480 8481 ins_encode %{ 8482 Register src_reg = as_Register($src$$reg); 8483 Register dst_reg = as_Register($dst$$reg); 8484 __ encode_klass_not_null(dst_reg, src_reg, t0); 8485 %} 8486 8487 ins_pipe(pipe_class_default); 8488 %} 8489 8490 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{ 8491 match(Set dst (DecodeNKlass src)); 8492 8493 effect(TEMP tmp); 8494 8495 ins_cost(ALU_COST); 8496 format %{ "decode_klass_not_null $dst, $src\t#@decodeKlass_not_null" %} 8497 8498 ins_encode %{ 8499 Register src_reg = as_Register($src$$reg); 8500 Register dst_reg = as_Register($dst$$reg); 8501 Register tmp_reg = as_Register($tmp$$reg); 8502 __ decode_klass_not_null(dst_reg, src_reg, tmp_reg); 8503 %} 8504 8505 ins_pipe(pipe_class_default); 8506 %} 8507 8508 // stack <-> reg and reg <-> reg shuffles with no conversion 8509 8510 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 8511 8512 match(Set dst (MoveF2I src)); 8513 8514 effect(DEF dst, USE src); 8515 8516 ins_cost(LOAD_COST); 8517 8518 format %{ "lw $dst, $src\t#@MoveF2I_stack_reg" %} 8519 8520 ins_encode %{ 8521 __ lw(as_Register($dst$$reg), Address(sp, $src$$disp)); 8522 %} 8523 8524 ins_pipe(iload_reg_reg); 8525 8526 %} 8527 8528 instruct MoveI2F_stack_reg(fRegF dst, stackSlotI src) %{ 8529 8530 match(Set dst (MoveI2F src)); 8531 8532 effect(DEF dst, USE src); 8533 8534 ins_cost(LOAD_COST); 8535 8536 format %{ "flw $dst, $src\t#@MoveI2F_stack_reg" %} 8537 8538 ins_encode %{ 8539 __ flw(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 8540 %} 8541 8542 ins_pipe(fp_load_mem_s); 8543 8544 %} 8545 8546 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 8547 8548 match(Set dst (MoveD2L src)); 8549 8550 effect(DEF dst, USE src); 8551 8552 ins_cost(LOAD_COST); 8553 8554 format %{ "ld $dst, $src\t#@MoveD2L_stack_reg" %} 8555 8556 ins_encode %{ 8557 __ ld(as_Register($dst$$reg), Address(sp, $src$$disp)); 8558 %} 8559 8560 ins_pipe(iload_reg_reg); 8561 8562 %} 8563 8564 instruct MoveL2D_stack_reg(fRegD dst, stackSlotL src) %{ 8565 8566 match(Set dst (MoveL2D src)); 8567 8568 effect(DEF dst, USE src); 8569 8570 ins_cost(LOAD_COST); 8571 8572 format %{ "fld $dst, $src\t#@MoveL2D_stack_reg" %} 8573 8574 ins_encode %{ 8575 __ fld(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 8576 %} 8577 8578 ins_pipe(fp_load_mem_d); 8579 8580 %} 8581 8582 instruct MoveF2I_reg_stack(stackSlotI dst, fRegF src) %{ 8583 8584 match(Set dst (MoveF2I src)); 8585 8586 effect(DEF dst, USE src); 8587 8588 ins_cost(STORE_COST); 8589 8590 format %{ "fsw $src, $dst\t#@MoveF2I_reg_stack" %} 8591 8592 ins_encode %{ 8593 __ fsw(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 8594 %} 8595 8596 ins_pipe(fp_store_reg_s); 8597 8598 %} 8599 8600 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 8601 8602 match(Set dst (MoveI2F src)); 8603 8604 effect(DEF dst, USE src); 8605 8606 ins_cost(STORE_COST); 8607 8608 format %{ "sw $src, $dst\t#@MoveI2F_reg_stack" %} 8609 8610 ins_encode %{ 8611 __ sw(as_Register($src$$reg), Address(sp, $dst$$disp)); 8612 %} 8613 8614 ins_pipe(istore_reg_reg); 8615 8616 %} 8617 8618 instruct MoveD2L_reg_stack(stackSlotL dst, fRegD src) %{ 8619 8620 match(Set dst (MoveD2L src)); 8621 8622 effect(DEF dst, USE src); 8623 8624 ins_cost(STORE_COST); 8625 8626 format %{ "fsd $dst, $src\t#@MoveD2L_reg_stack" %} 8627 8628 ins_encode %{ 8629 __ fsd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 8630 %} 8631 8632 ins_pipe(fp_store_reg_d); 8633 8634 %} 8635 8636 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 8637 8638 match(Set dst (MoveL2D src)); 8639 8640 effect(DEF dst, USE src); 8641 8642 ins_cost(STORE_COST); 8643 8644 format %{ "sd $src, $dst\t#@MoveL2D_reg_stack" %} 8645 8646 ins_encode %{ 8647 __ sd(as_Register($src$$reg), Address(sp, $dst$$disp)); 8648 %} 8649 8650 ins_pipe(istore_reg_reg); 8651 8652 %} 8653 8654 instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{ 8655 8656 match(Set dst (MoveF2I src)); 8657 8658 effect(DEF dst, USE src); 8659 8660 ins_cost(FMVX_COST); 8661 8662 format %{ "fmv.x.w $dst, $src\t#@MoveF2I_reg_reg" %} 8663 8664 ins_encode %{ 8665 __ fmv_x_w(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 8666 %} 8667 8668 ins_pipe(fp_f2i); 8669 8670 %} 8671 8672 instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{ 8673 8674 match(Set dst (MoveI2F src)); 8675 8676 effect(DEF dst, USE src); 8677 8678 ins_cost(FMVX_COST); 8679 8680 format %{ "fmv.w.x $dst, $src\t#@MoveI2F_reg_reg" %} 8681 8682 ins_encode %{ 8683 __ fmv_w_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8684 %} 8685 8686 ins_pipe(fp_i2f); 8687 8688 %} 8689 8690 instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ 8691 8692 match(Set dst (MoveD2L src)); 8693 8694 effect(DEF dst, USE src); 8695 8696 ins_cost(FMVX_COST); 8697 8698 format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %} 8699 8700 ins_encode %{ 8701 __ fmv_x_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 8702 %} 8703 8704 ins_pipe(fp_d2l); 8705 8706 %} 8707 8708 instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{ 8709 8710 match(Set dst (MoveL2D src)); 8711 8712 effect(DEF dst, USE src); 8713 8714 ins_cost(FMVX_COST); 8715 8716 format %{ "fmv.d.x $dst, $src\t#@MoveL2D_reg_reg" %} 8717 8718 ins_encode %{ 8719 __ fmv_d_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8720 %} 8721 8722 ins_pipe(fp_l2d); 8723 8724 %} 8725 8726 // ============================================================================ 8727 // Compare Instructions which set the result float comparisons in dest register. 8728 8729 instruct cmpF3_reg_reg(iRegINoSp dst, fRegF op1, fRegF op2) 8730 %{ 8731 match(Set dst (CmpF3 op1 op2)); 8732 8733 ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); 8734 format %{ "flt.s $dst, $op2, $op1\t#@cmpF3_reg_reg\n\t" 8735 "bgtz $dst, done\n\t" 8736 "feq.s $dst, $op1, $op2\n\t" 8737 "addi $dst, $dst, -1\n\t" 8738 "done:" 8739 %} 8740 8741 ins_encode %{ 8742 // we want -1 for unordered or less than, 0 for equal and 1 for greater than. 8743 __ float_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), 8744 as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); 8745 %} 8746 8747 ins_pipe(pipe_class_default); 8748 %} 8749 8750 instruct cmpD3_reg_reg(iRegINoSp dst, fRegD op1, fRegD op2) 8751 %{ 8752 match(Set dst (CmpD3 op1 op2)); 8753 8754 ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); 8755 format %{ "flt.d $dst, $op2, $op1\t#@cmpD3_reg_reg\n\t" 8756 "bgtz $dst, done\n\t" 8757 "feq.d $dst, $op1, $op2\n\t" 8758 "addi $dst, $dst, -1\n\t" 8759 "done:" 8760 %} 8761 8762 ins_encode %{ 8763 // we want -1 for unordered or less than, 0 for equal and 1 for greater than. 8764 __ double_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); 8765 %} 8766 8767 ins_pipe(pipe_class_default); 8768 %} 8769 8770 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2) 8771 %{ 8772 match(Set dst (CmpL3 op1 op2)); 8773 8774 ins_cost(ALU_COST * 3 + BRANCH_COST); 8775 format %{ "slt $dst, $op2, $op1\t#@cmpL3_reg_reg\n\t" 8776 "bnez $dst, done\n\t" 8777 "slt $dst, $op1, $op2\n\t" 8778 "neg $dst, $dst\n\t" 8779 "done:" 8780 %} 8781 ins_encode %{ 8782 __ cmp_l2i(t0, as_Register($op1$$reg), as_Register($op2$$reg)); 8783 __ mv(as_Register($dst$$reg), t0); 8784 %} 8785 8786 ins_pipe(pipe_class_default); 8787 %} 8788 8789 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2) 8790 %{ 8791 match(Set dst (CmpUL3 op1 op2)); 8792 8793 ins_cost(ALU_COST * 3 + BRANCH_COST); 8794 format %{ "sltu $dst, $op2, $op1\t#@cmpUL3_reg_reg\n\t" 8795 "bnez $dst, done\n\t" 8796 "sltu $dst, $op1, $op2\n\t" 8797 "neg $dst, $dst\n\t" 8798 "done:" 8799 %} 8800 ins_encode %{ 8801 __ cmp_ul2i(t0, as_Register($op1$$reg), as_Register($op2$$reg)); 8802 __ mv(as_Register($dst$$reg), t0); 8803 %} 8804 8805 ins_pipe(pipe_class_default); 8806 %} 8807 8808 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI op1, iRegI op2) 8809 %{ 8810 match(Set dst (CmpU3 op1 op2)); 8811 8812 ins_cost(ALU_COST * 3 + BRANCH_COST); 8813 format %{ "sltu $dst, $op2, $op1\t#@cmpU3_reg_reg\n\t" 8814 "bnez $dst, done\n\t" 8815 "sltu $dst, $op1, $op2\n\t" 8816 "neg $dst, $dst\n\t" 8817 "done:" 8818 %} 8819 ins_encode %{ 8820 __ cmp_uw2i(t0, as_Register($op1$$reg), as_Register($op2$$reg)); 8821 __ mv(as_Register($dst$$reg), t0); 8822 %} 8823 8824 ins_pipe(pipe_class_default); 8825 %} 8826 8827 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q) 8828 %{ 8829 match(Set dst (CmpLTMask p q)); 8830 8831 ins_cost(2 * ALU_COST); 8832 8833 format %{ "slt $dst, $p, $q\t#@cmpLTMask_reg_reg\n\t" 8834 "subw $dst, zr, $dst\t#@cmpLTMask_reg_reg" 8835 %} 8836 8837 ins_encode %{ 8838 __ slt(as_Register($dst$$reg), as_Register($p$$reg), as_Register($q$$reg)); 8839 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 8840 %} 8841 8842 ins_pipe(ialu_reg_reg); 8843 %} 8844 8845 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I op, immI0 zero) 8846 %{ 8847 match(Set dst (CmpLTMask op zero)); 8848 8849 ins_cost(ALU_COST); 8850 8851 format %{ "sraiw $dst, $dst, 31\t#@cmpLTMask_reg_reg" %} 8852 8853 ins_encode %{ 8854 __ sraiw(as_Register($dst$$reg), as_Register($op$$reg), 31); 8855 %} 8856 8857 ins_pipe(ialu_reg_shift); 8858 %} 8859 8860 8861 // ============================================================================ 8862 // Max and Min 8863 8864 instruct minI_reg_reg(iRegINoSp dst, iRegI src) 8865 %{ 8866 match(Set dst (MinI dst src)); 8867 8868 ins_cost(BRANCH_COST + ALU_COST); 8869 format %{ 8870 "ble $dst, $src, skip\t#@minI_reg_reg\n\t" 8871 "mv $dst, $src\n\t" 8872 "skip:" 8873 %} 8874 8875 ins_encode %{ 8876 Label Lskip; 8877 __ ble(as_Register($dst$$reg), as_Register($src$$reg), Lskip); 8878 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8879 __ bind(Lskip); 8880 %} 8881 8882 ins_pipe(pipe_class_compare); 8883 %} 8884 8885 instruct maxI_reg_reg(iRegINoSp dst, iRegI src) 8886 %{ 8887 match(Set dst (MaxI dst src)); 8888 8889 ins_cost(BRANCH_COST + ALU_COST); 8890 format %{ 8891 "bge $dst, $src, skip\t#@maxI_reg_reg\n\t" 8892 "mv $dst, $src\n\t" 8893 "skip:" 8894 %} 8895 8896 ins_encode %{ 8897 Label Lskip; 8898 __ bge(as_Register($dst$$reg), as_Register($src$$reg), Lskip); 8899 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8900 __ bind(Lskip); 8901 %} 8902 8903 ins_pipe(pipe_class_compare); 8904 %} 8905 8906 // special case for comparing with zero 8907 // n.b. this is selected in preference to the rule above because it 8908 // avoids loading constant 0 into a source register 8909 8910 instruct minI_reg_zero(iRegINoSp dst, immI0 zero) 8911 %{ 8912 match(Set dst (MinI dst zero)); 8913 match(Set dst (MinI zero dst)); 8914 8915 ins_cost(BRANCH_COST + ALU_COST); 8916 format %{ 8917 "blez $dst, skip\t#@minI_reg_zero\n\t" 8918 "mv $dst, zr\n\t" 8919 "skip:" 8920 %} 8921 8922 ins_encode %{ 8923 Label Lskip; 8924 __ blez(as_Register($dst$$reg), Lskip); 8925 __ mv(as_Register($dst$$reg), zr); 8926 __ bind(Lskip); 8927 %} 8928 8929 ins_pipe(pipe_class_compare); 8930 %} 8931 8932 instruct maxI_reg_zero(iRegINoSp dst, immI0 zero) 8933 %{ 8934 match(Set dst (MaxI dst zero)); 8935 match(Set dst (MaxI zero dst)); 8936 8937 ins_cost(BRANCH_COST + ALU_COST); 8938 format %{ 8939 "bgez $dst, skip\t#@maxI_reg_zero\n\t" 8940 "mv $dst, zr\n\t" 8941 "skip:" 8942 %} 8943 8944 ins_encode %{ 8945 Label Lskip; 8946 __ bgez(as_Register($dst$$reg), Lskip); 8947 __ mv(as_Register($dst$$reg), zr); 8948 __ bind(Lskip); 8949 %} 8950 8951 ins_pipe(pipe_class_compare); 8952 %} 8953 8954 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 8955 %{ 8956 match(Set dst (MinI src1 src2)); 8957 8958 effect(DEF dst, USE src1, USE src2); 8959 8960 ins_cost(BRANCH_COST + ALU_COST * 2); 8961 format %{ 8962 "ble $src1, $src2, Lsrc1\t#@minI_rReg\n\t" 8963 "mv $dst, $src2\n\t" 8964 "j Ldone\n\t" 8965 "Lsrc1:\n\t" 8966 "mv $dst, $src1\n\t" 8967 "Ldone:" 8968 %} 8969 8970 ins_encode %{ 8971 Label Lsrc1, Ldone; 8972 __ ble(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); 8973 __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); 8974 __ j(Ldone); 8975 __ bind(Lsrc1); 8976 __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); 8977 __ bind(Ldone); 8978 %} 8979 8980 ins_pipe(pipe_class_compare); 8981 %} 8982 8983 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 8984 %{ 8985 match(Set dst (MaxI src1 src2)); 8986 8987 effect(DEF dst, USE src1, USE src2); 8988 8989 ins_cost(BRANCH_COST + ALU_COST * 2); 8990 format %{ 8991 "bge $src1, $src2, Lsrc1\t#@maxI_rReg\n\t" 8992 "mv $dst, $src2\n\t" 8993 "j Ldone\n\t" 8994 "Lsrc1:\n\t" 8995 "mv $dst, $src1\n\t" 8996 "Ldone:" 8997 %} 8998 8999 ins_encode %{ 9000 Label Lsrc1, Ldone; 9001 __ bge(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); 9002 __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); 9003 __ j(Ldone); 9004 __ bind(Lsrc1); 9005 __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); 9006 __ bind(Ldone); 9007 9008 %} 9009 9010 ins_pipe(pipe_class_compare); 9011 %} 9012 9013 // ============================================================================ 9014 // Branch Instructions 9015 // Direct Branch. 9016 instruct branch(label lbl) 9017 %{ 9018 match(Goto); 9019 9020 effect(USE lbl); 9021 9022 ins_cost(BRANCH_COST); 9023 format %{ "j $lbl\t#@branch" %} 9024 9025 ins_encode(riscv_enc_j(lbl)); 9026 9027 ins_pipe(pipe_branch); 9028 %} 9029 9030 // ============================================================================ 9031 // Compare and Branch Instructions 9032 9033 // Patterns for short (< 12KiB) variants 9034 9035 // Compare flags and branch near instructions. 9036 instruct cmpFlag_branch(cmpOpEqNe cmp, rFlagsReg cr, label lbl) %{ 9037 match(If cmp cr); 9038 effect(USE lbl); 9039 9040 ins_cost(BRANCH_COST); 9041 format %{ "b$cmp $cr, zr, $lbl\t#@cmpFlag_branch" %} 9042 9043 ins_encode %{ 9044 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label)); 9045 %} 9046 ins_pipe(pipe_cmpz_branch); 9047 ins_short_branch(1); 9048 %} 9049 9050 // Compare signed int and branch near instructions 9051 instruct cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) 9052 %{ 9053 // Same match rule as `far_cmpI_branch'. 9054 match(If cmp (CmpI op1 op2)); 9055 9056 effect(USE lbl); 9057 9058 ins_cost(BRANCH_COST); 9059 9060 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_branch" %} 9061 9062 ins_encode %{ 9063 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 9064 %} 9065 9066 ins_pipe(pipe_cmp_branch); 9067 ins_short_branch(1); 9068 %} 9069 9070 instruct cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) 9071 %{ 9072 // Same match rule as `far_cmpI_loop'. 9073 match(CountedLoopEnd cmp (CmpI op1 op2)); 9074 9075 effect(USE lbl); 9076 9077 ins_cost(BRANCH_COST); 9078 9079 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_loop" %} 9080 9081 ins_encode %{ 9082 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 9083 %} 9084 9085 ins_pipe(pipe_cmp_branch); 9086 ins_short_branch(1); 9087 %} 9088 9089 // Compare unsigned int and branch near instructions 9090 instruct cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) 9091 %{ 9092 // Same match rule as `far_cmpU_branch'. 9093 match(If cmp (CmpU op1 op2)); 9094 9095 effect(USE lbl); 9096 9097 ins_cost(BRANCH_COST); 9098 9099 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpU_branch" %} 9100 9101 ins_encode %{ 9102 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9103 as_Register($op2$$reg), *($lbl$$label)); 9104 %} 9105 9106 ins_pipe(pipe_cmp_branch); 9107 ins_short_branch(1); 9108 %} 9109 9110 // Compare signed long and branch near instructions 9111 instruct cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) 9112 %{ 9113 // Same match rule as `far_cmpL_branch'. 9114 match(If cmp (CmpL op1 op2)); 9115 9116 effect(USE lbl); 9117 9118 ins_cost(BRANCH_COST); 9119 9120 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_branch" %} 9121 9122 ins_encode %{ 9123 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 9124 %} 9125 9126 ins_pipe(pipe_cmp_branch); 9127 ins_short_branch(1); 9128 %} 9129 9130 instruct cmpL_loop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) 9131 %{ 9132 // Same match rule as `far_cmpL_loop'. 9133 match(CountedLoopEnd cmp (CmpL op1 op2)); 9134 9135 effect(USE lbl); 9136 9137 ins_cost(BRANCH_COST); 9138 9139 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_loop" %} 9140 9141 ins_encode %{ 9142 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 9143 %} 9144 9145 ins_pipe(pipe_cmp_branch); 9146 ins_short_branch(1); 9147 %} 9148 9149 // Compare unsigned long and branch near instructions 9150 instruct cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) 9151 %{ 9152 // Same match rule as `far_cmpUL_branch'. 9153 match(If cmp (CmpUL op1 op2)); 9154 9155 effect(USE lbl); 9156 9157 ins_cost(BRANCH_COST); 9158 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpUL_branch" %} 9159 9160 ins_encode %{ 9161 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9162 as_Register($op2$$reg), *($lbl$$label)); 9163 %} 9164 9165 ins_pipe(pipe_cmp_branch); 9166 ins_short_branch(1); 9167 %} 9168 9169 // Compare pointer and branch near instructions 9170 instruct cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) 9171 %{ 9172 // Same match rule as `far_cmpP_branch'. 9173 match(If cmp (CmpP op1 op2)); 9174 9175 effect(USE lbl); 9176 9177 ins_cost(BRANCH_COST); 9178 9179 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpP_branch" %} 9180 9181 ins_encode %{ 9182 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9183 as_Register($op2$$reg), *($lbl$$label)); 9184 %} 9185 9186 ins_pipe(pipe_cmp_branch); 9187 ins_short_branch(1); 9188 %} 9189 9190 // Compare narrow pointer and branch near instructions 9191 instruct cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) 9192 %{ 9193 // Same match rule as `far_cmpN_branch'. 9194 match(If cmp (CmpN op1 op2)); 9195 9196 effect(USE lbl); 9197 9198 ins_cost(BRANCH_COST); 9199 9200 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpN_branch" %} 9201 9202 ins_encode %{ 9203 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9204 as_Register($op2$$reg), *($lbl$$label)); 9205 %} 9206 9207 ins_pipe(pipe_cmp_branch); 9208 ins_short_branch(1); 9209 %} 9210 9211 // Compare float and branch near instructions 9212 instruct cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) 9213 %{ 9214 // Same match rule as `far_cmpF_branch'. 9215 match(If cmp (CmpF op1 op2)); 9216 9217 effect(USE lbl); 9218 9219 ins_cost(XFER_COST + BRANCH_COST); 9220 format %{ "float_b$cmp $op1, $op2, $lbl \t#@cmpF_branch"%} 9221 9222 ins_encode %{ 9223 __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), *($lbl$$label)); 9224 %} 9225 9226 ins_pipe(pipe_class_compare); 9227 ins_short_branch(1); 9228 %} 9229 9230 // Compare double and branch near instructions 9231 instruct cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) 9232 %{ 9233 // Same match rule as `far_cmpD_branch'. 9234 match(If cmp (CmpD op1 op2)); 9235 effect(USE lbl); 9236 9237 ins_cost(XFER_COST + BRANCH_COST); 9238 format %{ "double_b$cmp $op1, $op2, $lbl\t#@cmpD_branch"%} 9239 9240 ins_encode %{ 9241 __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), 9242 as_FloatRegister($op2$$reg), *($lbl$$label)); 9243 %} 9244 9245 ins_pipe(pipe_class_compare); 9246 ins_short_branch(1); 9247 %} 9248 9249 // Compare signed int with zero and branch near instructions 9250 instruct cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9251 %{ 9252 // Same match rule as `far_cmpI_reg_imm0_branch'. 9253 match(If cmp (CmpI op1 zero)); 9254 9255 effect(USE op1, USE lbl); 9256 9257 ins_cost(BRANCH_COST); 9258 format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_branch" %} 9259 9260 ins_encode %{ 9261 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9262 %} 9263 9264 ins_pipe(pipe_cmpz_branch); 9265 ins_short_branch(1); 9266 %} 9267 9268 instruct cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9269 %{ 9270 // Same match rule as `far_cmpI_reg_imm0_loop'. 9271 match(CountedLoopEnd cmp (CmpI op1 zero)); 9272 9273 effect(USE op1, USE lbl); 9274 9275 ins_cost(BRANCH_COST); 9276 9277 format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_loop" %} 9278 9279 ins_encode %{ 9280 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9281 %} 9282 9283 ins_pipe(pipe_cmpz_branch); 9284 ins_short_branch(1); 9285 %} 9286 9287 // Compare unsigned int with zero and branch near instructions 9288 instruct cmpUEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) 9289 %{ 9290 // Same match rule as `far_cmpUEqNeLeGt_reg_imm0_branch'. 9291 match(If cmp (CmpU op1 zero)); 9292 9293 effect(USE op1, USE lbl); 9294 9295 ins_cost(BRANCH_COST); 9296 9297 format %{ "b$cmp $op1, zr, $lbl\t#@cmpUEqNeLeGt_reg_imm0_branch" %} 9298 9299 ins_encode %{ 9300 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9301 %} 9302 9303 ins_pipe(pipe_cmpz_branch); 9304 ins_short_branch(1); 9305 %} 9306 9307 // Compare signed long with zero and branch near instructions 9308 instruct cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9309 %{ 9310 // Same match rule as `far_cmpL_reg_imm0_branch'. 9311 match(If cmp (CmpL op1 zero)); 9312 9313 effect(USE op1, USE lbl); 9314 9315 ins_cost(BRANCH_COST); 9316 9317 format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_branch" %} 9318 9319 ins_encode %{ 9320 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9321 %} 9322 9323 ins_pipe(pipe_cmpz_branch); 9324 ins_short_branch(1); 9325 %} 9326 9327 instruct cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9328 %{ 9329 // Same match rule as `far_cmpL_reg_imm0_loop'. 9330 match(CountedLoopEnd cmp (CmpL op1 zero)); 9331 9332 effect(USE op1, USE lbl); 9333 9334 ins_cost(BRANCH_COST); 9335 9336 format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_loop" %} 9337 9338 ins_encode %{ 9339 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9340 %} 9341 9342 ins_pipe(pipe_cmpz_branch); 9343 ins_short_branch(1); 9344 %} 9345 9346 // Compare unsigned long with zero and branch near instructions 9347 instruct cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) 9348 %{ 9349 // Same match rule as `far_cmpULEqNeLeGt_reg_imm0_branch'. 9350 match(If cmp (CmpUL op1 zero)); 9351 9352 effect(USE op1, USE lbl); 9353 9354 ins_cost(BRANCH_COST); 9355 9356 format %{ "b$cmp $op1, zr, $lbl\t#@cmpULEqNeLeGt_reg_imm0_branch" %} 9357 9358 ins_encode %{ 9359 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9360 %} 9361 9362 ins_pipe(pipe_cmpz_branch); 9363 ins_short_branch(1); 9364 %} 9365 9366 // Compare pointer with zero and branch near instructions 9367 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ 9368 // Same match rule as `far_cmpP_reg_imm0_branch'. 9369 match(If cmp (CmpP op1 zero)); 9370 effect(USE lbl); 9371 9372 ins_cost(BRANCH_COST); 9373 format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_imm0_branch" %} 9374 9375 ins_encode %{ 9376 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9377 %} 9378 9379 ins_pipe(pipe_cmpz_branch); 9380 ins_short_branch(1); 9381 %} 9382 9383 // Compare narrow pointer with zero and branch near instructions 9384 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ 9385 // Same match rule as `far_cmpN_reg_imm0_branch'. 9386 match(If cmp (CmpN op1 zero)); 9387 effect(USE lbl); 9388 9389 ins_cost(BRANCH_COST); 9390 9391 format %{ "b$cmp $op1, zr, $lbl\t#@cmpN_imm0_branch" %} 9392 9393 ins_encode %{ 9394 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9395 %} 9396 9397 ins_pipe(pipe_cmpz_branch); 9398 ins_short_branch(1); 9399 %} 9400 9401 // Compare narrow pointer with pointer zero and branch near instructions 9402 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ 9403 // Same match rule as `far_cmpP_narrowOop_imm0_branch'. 9404 match(If cmp (CmpP (DecodeN op1) zero)); 9405 effect(USE lbl); 9406 9407 ins_cost(BRANCH_COST); 9408 format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_narrowOop_imm0_branch" %} 9409 9410 ins_encode %{ 9411 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9412 %} 9413 9414 ins_pipe(pipe_cmpz_branch); 9415 ins_short_branch(1); 9416 %} 9417 9418 // Patterns for far (20KiB) variants 9419 9420 instruct far_cmpFlag_branch(cmpOp cmp, rFlagsReg cr, label lbl) %{ 9421 match(If cmp cr); 9422 effect(USE lbl); 9423 9424 ins_cost(BRANCH_COST); 9425 format %{ "far_b$cmp $cr, zr, $lbl\t#@far_cmpFlag_branch"%} 9426 9427 ins_encode %{ 9428 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label), /* is_far */ true); 9429 %} 9430 9431 ins_pipe(pipe_cmpz_branch); 9432 %} 9433 9434 // Compare signed int and branch far instructions 9435 instruct far_cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ 9436 match(If cmp (CmpI op1 op2)); 9437 effect(USE lbl); 9438 9439 ins_cost(BRANCH_COST * 2); 9440 9441 // the format instruction [far_b$cmp] here is be used as two insructions 9442 // in macroassembler: b$not_cmp(op1, op2, done), j($lbl), bind(done) 9443 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_branch" %} 9444 9445 ins_encode %{ 9446 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9447 %} 9448 9449 ins_pipe(pipe_cmp_branch); 9450 %} 9451 9452 instruct far_cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ 9453 match(CountedLoopEnd cmp (CmpI op1 op2)); 9454 effect(USE lbl); 9455 9456 ins_cost(BRANCH_COST * 2); 9457 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_loop" %} 9458 9459 ins_encode %{ 9460 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9461 %} 9462 9463 ins_pipe(pipe_cmp_branch); 9464 %} 9465 9466 instruct far_cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) %{ 9467 match(If cmp (CmpU op1 op2)); 9468 effect(USE lbl); 9469 9470 ins_cost(BRANCH_COST * 2); 9471 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpU_branch" %} 9472 9473 ins_encode %{ 9474 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9475 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9476 %} 9477 9478 ins_pipe(pipe_cmp_branch); 9479 %} 9480 9481 instruct far_cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ 9482 match(If cmp (CmpL op1 op2)); 9483 effect(USE lbl); 9484 9485 ins_cost(BRANCH_COST * 2); 9486 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_branch" %} 9487 9488 ins_encode %{ 9489 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9490 %} 9491 9492 ins_pipe(pipe_cmp_branch); 9493 %} 9494 9495 instruct far_cmpLloop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ 9496 match(CountedLoopEnd cmp (CmpL op1 op2)); 9497 effect(USE lbl); 9498 9499 ins_cost(BRANCH_COST * 2); 9500 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_loop" %} 9501 9502 ins_encode %{ 9503 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9504 %} 9505 9506 ins_pipe(pipe_cmp_branch); 9507 %} 9508 9509 instruct far_cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) %{ 9510 match(If cmp (CmpUL op1 op2)); 9511 effect(USE lbl); 9512 9513 ins_cost(BRANCH_COST * 2); 9514 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpUL_branch" %} 9515 9516 ins_encode %{ 9517 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9518 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9519 %} 9520 9521 ins_pipe(pipe_cmp_branch); 9522 %} 9523 9524 instruct far_cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) 9525 %{ 9526 match(If cmp (CmpP op1 op2)); 9527 9528 effect(USE lbl); 9529 9530 ins_cost(BRANCH_COST * 2); 9531 9532 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpP_branch" %} 9533 9534 ins_encode %{ 9535 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9536 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9537 %} 9538 9539 ins_pipe(pipe_cmp_branch); 9540 %} 9541 9542 instruct far_cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) 9543 %{ 9544 match(If cmp (CmpN op1 op2)); 9545 9546 effect(USE lbl); 9547 9548 ins_cost(BRANCH_COST * 2); 9549 9550 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpN_branch" %} 9551 9552 ins_encode %{ 9553 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9554 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9555 %} 9556 9557 ins_pipe(pipe_cmp_branch); 9558 %} 9559 9560 // Float compare and branch instructions 9561 instruct far_cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) 9562 %{ 9563 match(If cmp (CmpF op1 op2)); 9564 9565 effect(USE lbl); 9566 9567 ins_cost(XFER_COST + BRANCH_COST * 2); 9568 format %{ "far_float_b$cmp $op1, $op2, $lbl\t#@far_cmpF_branch"%} 9569 9570 ins_encode %{ 9571 __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), 9572 *($lbl$$label), /* is_far */ true); 9573 %} 9574 9575 ins_pipe(pipe_class_compare); 9576 %} 9577 9578 // Double compare and branch instructions 9579 instruct far_cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) 9580 %{ 9581 match(If cmp (CmpD op1 op2)); 9582 effect(USE lbl); 9583 9584 ins_cost(XFER_COST + BRANCH_COST * 2); 9585 format %{ "far_double_b$cmp $op1, $op2, $lbl\t#@far_cmpD_branch"%} 9586 9587 ins_encode %{ 9588 __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), 9589 as_FloatRegister($op2$$reg), *($lbl$$label), /* is_far */ true); 9590 %} 9591 9592 ins_pipe(pipe_class_compare); 9593 %} 9594 9595 instruct far_cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9596 %{ 9597 match(If cmp (CmpI op1 zero)); 9598 9599 effect(USE op1, USE lbl); 9600 9601 ins_cost(BRANCH_COST * 2); 9602 9603 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_branch" %} 9604 9605 ins_encode %{ 9606 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9607 %} 9608 9609 ins_pipe(pipe_cmpz_branch); 9610 %} 9611 9612 instruct far_cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9613 %{ 9614 match(CountedLoopEnd cmp (CmpI op1 zero)); 9615 9616 effect(USE op1, USE lbl); 9617 9618 ins_cost(BRANCH_COST * 2); 9619 9620 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_loop" %} 9621 9622 ins_encode %{ 9623 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9624 %} 9625 9626 ins_pipe(pipe_cmpz_branch); 9627 %} 9628 9629 instruct far_cmpUEqNeLeGt_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) 9630 %{ 9631 match(If cmp (CmpU op1 zero)); 9632 9633 effect(USE op1, USE lbl); 9634 9635 ins_cost(BRANCH_COST * 2); 9636 9637 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpUEqNeLeGt_imm0_branch" %} 9638 9639 ins_encode %{ 9640 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9641 %} 9642 9643 ins_pipe(pipe_cmpz_branch); 9644 %} 9645 9646 // compare lt/ge unsigned instructs has no short instruct with same match 9647 instruct far_cmpULtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegI op1, immI0 zero, label lbl) 9648 %{ 9649 match(If cmp (CmpU op1 zero)); 9650 9651 effect(USE op1, USE lbl); 9652 9653 ins_cost(BRANCH_COST); 9654 9655 format %{ "j $lbl if $cmp == ge\t#@far_cmpULtGe_reg_imm0_branch" %} 9656 9657 ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); 9658 9659 ins_pipe(pipe_cmpz_branch); 9660 %} 9661 9662 instruct far_cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9663 %{ 9664 match(If cmp (CmpL op1 zero)); 9665 9666 effect(USE op1, USE lbl); 9667 9668 ins_cost(BRANCH_COST * 2); 9669 9670 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_branch" %} 9671 9672 ins_encode %{ 9673 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9674 %} 9675 9676 ins_pipe(pipe_cmpz_branch); 9677 %} 9678 9679 instruct far_cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9680 %{ 9681 match(CountedLoopEnd cmp (CmpL op1 zero)); 9682 9683 effect(USE op1, USE lbl); 9684 9685 ins_cost(BRANCH_COST * 2); 9686 9687 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_loop" %} 9688 9689 ins_encode %{ 9690 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9691 %} 9692 9693 ins_pipe(pipe_cmpz_branch); 9694 %} 9695 9696 instruct far_cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) 9697 %{ 9698 match(If cmp (CmpUL op1 zero)); 9699 9700 effect(USE op1, USE lbl); 9701 9702 ins_cost(BRANCH_COST * 2); 9703 9704 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpULEqNeLeGt_reg_imm0_branch" %} 9705 9706 ins_encode %{ 9707 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9708 %} 9709 9710 ins_pipe(pipe_cmpz_branch); 9711 %} 9712 9713 // compare lt/ge unsigned instructs has no short instruct with same match 9714 instruct far_cmpULLtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegL op1, immL0 zero, label lbl) 9715 %{ 9716 match(If cmp (CmpUL op1 zero)); 9717 9718 effect(USE op1, USE lbl); 9719 9720 ins_cost(BRANCH_COST); 9721 9722 format %{ "j $lbl if $cmp == ge\t#@far_cmpULLtGe_reg_imm0_branch" %} 9723 9724 ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); 9725 9726 ins_pipe(pipe_cmpz_branch); 9727 %} 9728 9729 instruct far_cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ 9730 match(If cmp (CmpP op1 zero)); 9731 effect(USE lbl); 9732 9733 ins_cost(BRANCH_COST * 2); 9734 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_imm0_branch" %} 9735 9736 ins_encode %{ 9737 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9738 %} 9739 9740 ins_pipe(pipe_cmpz_branch); 9741 %} 9742 9743 instruct far_cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ 9744 match(If cmp (CmpN op1 zero)); 9745 effect(USE lbl); 9746 9747 ins_cost(BRANCH_COST * 2); 9748 9749 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpN_imm0_branch" %} 9750 9751 ins_encode %{ 9752 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9753 %} 9754 9755 ins_pipe(pipe_cmpz_branch); 9756 %} 9757 9758 instruct far_cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ 9759 match(If cmp (CmpP (DecodeN op1) zero)); 9760 effect(USE lbl); 9761 9762 ins_cost(BRANCH_COST * 2); 9763 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_narrowOop_imm0_branch" %} 9764 9765 ins_encode %{ 9766 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9767 %} 9768 9769 ins_pipe(pipe_cmpz_branch); 9770 %} 9771 9772 // ============================================================================ 9773 // Conditional Move Instructions 9774 instruct cmovI_cmpI(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOp cop) %{ 9775 match(Set dst (CMoveI (Binary cop (CmpI op1 op2)) (Binary dst src))); 9776 ins_cost(ALU_COST + BRANCH_COST); 9777 9778 format %{ 9779 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpI\n\t" 9780 %} 9781 9782 ins_encode %{ 9783 __ enc_cmove($cop$$cmpcode, 9784 as_Register($op1$$reg), as_Register($op2$$reg), 9785 as_Register($dst$$reg), as_Register($src$$reg)); 9786 %} 9787 9788 ins_pipe(pipe_class_compare); 9789 %} 9790 9791 instruct cmovI_cmpU(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOpU cop) %{ 9792 match(Set dst (CMoveI (Binary cop (CmpU op1 op2)) (Binary dst src))); 9793 ins_cost(ALU_COST + BRANCH_COST); 9794 9795 format %{ 9796 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpU\n\t" 9797 %} 9798 9799 ins_encode %{ 9800 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9801 as_Register($op1$$reg), as_Register($op2$$reg), 9802 as_Register($dst$$reg), as_Register($src$$reg)); 9803 %} 9804 9805 ins_pipe(pipe_class_compare); 9806 %} 9807 9808 instruct cmovI_cmpL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOp cop) %{ 9809 match(Set dst (CMoveI (Binary cop (CmpL op1 op2)) (Binary dst src))); 9810 ins_cost(ALU_COST + BRANCH_COST); 9811 9812 format %{ 9813 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpL\n\t" 9814 %} 9815 9816 ins_encode %{ 9817 __ enc_cmove($cop$$cmpcode, 9818 as_Register($op1$$reg), as_Register($op2$$reg), 9819 as_Register($dst$$reg), as_Register($src$$reg)); 9820 %} 9821 9822 ins_pipe(pipe_class_compare); 9823 %} 9824 9825 instruct cmovI_cmpUL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOpU cop) %{ 9826 match(Set dst (CMoveI (Binary cop (CmpUL op1 op2)) (Binary dst src))); 9827 ins_cost(ALU_COST + BRANCH_COST); 9828 9829 format %{ 9830 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpUL\n\t" 9831 %} 9832 9833 ins_encode %{ 9834 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9835 as_Register($op1$$reg), as_Register($op2$$reg), 9836 as_Register($dst$$reg), as_Register($src$$reg)); 9837 %} 9838 9839 ins_pipe(pipe_class_compare); 9840 %} 9841 9842 instruct cmovI_cmpN(iRegINoSp dst, iRegI src, iRegN op1, iRegN op2, cmpOpU cop) %{ 9843 match(Set dst (CMoveI (Binary cop (CmpN op1 op2)) (Binary dst src))); 9844 ins_cost(ALU_COST + BRANCH_COST); 9845 9846 format %{ 9847 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpN\n\t" 9848 %} 9849 9850 ins_encode %{ 9851 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9852 as_Register($op1$$reg), as_Register($op2$$reg), 9853 as_Register($dst$$reg), as_Register($src$$reg)); 9854 %} 9855 9856 ins_pipe(pipe_class_compare); 9857 %} 9858 9859 instruct cmovI_cmpP(iRegINoSp dst, iRegI src, iRegP op1, iRegP op2, cmpOpU cop) %{ 9860 match(Set dst (CMoveI (Binary cop (CmpP op1 op2)) (Binary dst src))); 9861 ins_cost(ALU_COST + BRANCH_COST); 9862 9863 format %{ 9864 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpP\n\t" 9865 %} 9866 9867 ins_encode %{ 9868 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9869 as_Register($op1$$reg), as_Register($op2$$reg), 9870 as_Register($dst$$reg), as_Register($src$$reg)); 9871 %} 9872 9873 ins_pipe(pipe_class_compare); 9874 %} 9875 9876 instruct cmovL_cmpL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOp cop) %{ 9877 match(Set dst (CMoveL (Binary cop (CmpL op1 op2)) (Binary dst src))); 9878 ins_cost(ALU_COST + BRANCH_COST); 9879 9880 format %{ 9881 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpL\n\t" 9882 %} 9883 9884 ins_encode %{ 9885 __ enc_cmove($cop$$cmpcode, 9886 as_Register($op1$$reg), as_Register($op2$$reg), 9887 as_Register($dst$$reg), as_Register($src$$reg)); 9888 %} 9889 9890 ins_pipe(pipe_class_compare); 9891 %} 9892 9893 instruct cmovL_cmpUL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOpU cop) %{ 9894 match(Set dst (CMoveL (Binary cop (CmpUL op1 op2)) (Binary dst src))); 9895 ins_cost(ALU_COST + BRANCH_COST); 9896 9897 format %{ 9898 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpUL\n\t" 9899 %} 9900 9901 ins_encode %{ 9902 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9903 as_Register($op1$$reg), as_Register($op2$$reg), 9904 as_Register($dst$$reg), as_Register($src$$reg)); 9905 %} 9906 9907 ins_pipe(pipe_class_compare); 9908 %} 9909 9910 instruct cmovL_cmpI(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOp cop) %{ 9911 match(Set dst (CMoveL (Binary cop (CmpI op1 op2)) (Binary dst src))); 9912 ins_cost(ALU_COST + BRANCH_COST); 9913 9914 format %{ 9915 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpI\n\t" 9916 %} 9917 9918 ins_encode %{ 9919 __ enc_cmove($cop$$cmpcode, 9920 as_Register($op1$$reg), as_Register($op2$$reg), 9921 as_Register($dst$$reg), as_Register($src$$reg)); 9922 %} 9923 9924 ins_pipe(pipe_class_compare); 9925 %} 9926 9927 instruct cmovL_cmpU(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOpU cop) %{ 9928 match(Set dst (CMoveL (Binary cop (CmpU op1 op2)) (Binary dst src))); 9929 ins_cost(ALU_COST + BRANCH_COST); 9930 9931 format %{ 9932 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpU\n\t" 9933 %} 9934 9935 ins_encode %{ 9936 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9937 as_Register($op1$$reg), as_Register($op2$$reg), 9938 as_Register($dst$$reg), as_Register($src$$reg)); 9939 %} 9940 9941 ins_pipe(pipe_class_compare); 9942 %} 9943 9944 instruct cmovL_cmpN(iRegLNoSp dst, iRegL src, iRegN op1, iRegN op2, cmpOpU cop) %{ 9945 match(Set dst (CMoveL (Binary cop (CmpN op1 op2)) (Binary dst src))); 9946 ins_cost(ALU_COST + BRANCH_COST); 9947 9948 format %{ 9949 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpN\n\t" 9950 %} 9951 9952 ins_encode %{ 9953 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9954 as_Register($op1$$reg), as_Register($op2$$reg), 9955 as_Register($dst$$reg), as_Register($src$$reg)); 9956 %} 9957 9958 ins_pipe(pipe_class_compare); 9959 %} 9960 9961 instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop) %{ 9962 match(Set dst (CMoveL (Binary cop (CmpP op1 op2)) (Binary dst src))); 9963 ins_cost(ALU_COST + BRANCH_COST); 9964 9965 format %{ 9966 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpP\n\t" 9967 %} 9968 9969 ins_encode %{ 9970 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9971 as_Register($op1$$reg), as_Register($op2$$reg), 9972 as_Register($dst$$reg), as_Register($src$$reg)); 9973 %} 9974 9975 ins_pipe(pipe_class_compare); 9976 %} 9977 9978 // ============================================================================ 9979 // Procedure Call/Return Instructions 9980 9981 // Call Java Static Instruction 9982 // Note: If this code changes, the corresponding ret_addr_offset() and 9983 // compute_padding() functions will have to be adjusted. 9984 instruct CallStaticJavaDirect(method meth) 9985 %{ 9986 match(CallStaticJava); 9987 9988 effect(USE meth); 9989 9990 ins_cost(BRANCH_COST); 9991 9992 format %{ "CALL,static $meth\t#@CallStaticJavaDirect" %} 9993 9994 ins_encode(riscv_enc_java_static_call(meth), 9995 riscv_enc_call_epilog); 9996 9997 ins_pipe(pipe_class_call); 9998 ins_alignment(4); 9999 %} 10000 10001 // TO HERE 10002 10003 // Call Java Dynamic Instruction 10004 // Note: If this code changes, the corresponding ret_addr_offset() and 10005 // compute_padding() functions will have to be adjusted. 10006 instruct CallDynamicJavaDirect(method meth, rFlagsReg cr) 10007 %{ 10008 match(CallDynamicJava); 10009 10010 effect(USE meth, KILL cr); 10011 10012 ins_cost(BRANCH_COST + ALU_COST * 5); 10013 10014 format %{ "CALL,dynamic $meth\t#@CallDynamicJavaDirect" %} 10015 10016 ins_encode(riscv_enc_java_dynamic_call(meth), 10017 riscv_enc_call_epilog); 10018 10019 ins_pipe(pipe_class_call); 10020 ins_alignment(4); 10021 %} 10022 10023 // Call Runtime Instruction 10024 10025 instruct CallRuntimeDirect(method meth, rFlagsReg cr) 10026 %{ 10027 match(CallRuntime); 10028 10029 effect(USE meth, KILL cr); 10030 10031 ins_cost(BRANCH_COST); 10032 10033 format %{ "CALL, runtime $meth\t#@CallRuntimeDirect" %} 10034 10035 ins_encode(riscv_enc_java_to_runtime(meth)); 10036 10037 ins_pipe(pipe_class_call); 10038 %} 10039 10040 // Call Runtime Instruction 10041 10042 instruct CallLeafDirect(method meth, rFlagsReg cr) 10043 %{ 10044 match(CallLeaf); 10045 10046 effect(USE meth, KILL cr); 10047 10048 ins_cost(BRANCH_COST); 10049 10050 format %{ "CALL, runtime leaf $meth\t#@CallLeafDirect" %} 10051 10052 ins_encode(riscv_enc_java_to_runtime(meth)); 10053 10054 ins_pipe(pipe_class_call); 10055 %} 10056 10057 // Call Runtime Instruction 10058 10059 instruct CallLeafNoFPDirect(method meth, rFlagsReg cr) 10060 %{ 10061 match(CallLeafNoFP); 10062 10063 effect(USE meth, KILL cr); 10064 10065 ins_cost(BRANCH_COST); 10066 10067 format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %} 10068 10069 ins_encode(riscv_enc_java_to_runtime(meth)); 10070 10071 ins_pipe(pipe_class_call); 10072 %} 10073 10074 // ============================================================================ 10075 // Partial Subtype Check 10076 // 10077 // superklass array for an instance of the superklass. Set a hidden 10078 // internal cache on a hit (cache is checked with exposed code in 10079 // gen_subtype_check()). Return zero for a hit. The encoding 10080 // ALSO sets flags. 10081 10082 instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, rFlagsReg cr) 10083 %{ 10084 match(Set result (PartialSubtypeCheck sub super)); 10085 effect(KILL tmp, KILL cr); 10086 10087 ins_cost(11 * DEFAULT_COST); 10088 format %{ "partialSubtypeCheck $result, $sub, $super\t#@partialSubtypeCheck" %} 10089 10090 ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); 10091 10092 opcode(0x1); // Force zero of result reg on hit 10093 10094 ins_pipe(pipe_class_memory); 10095 %} 10096 10097 instruct partialSubtypeCheckConstSuper(iRegP_R14 sub, iRegP_R10 super_reg, immP super_con, iRegP_R15 result, 10098 iRegP_R11 tmpR11, iRegP_R12 tmpR12, iRegP_R13 tmpR13, iRegP_R16 tmpR16) 10099 %{ 10100 predicate(UseSecondarySupersTable); 10101 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 10102 effect(TEMP tmpR11, TEMP tmpR12, TEMP tmpR13, TEMP tmpR16); 10103 10104 ins_cost(7 * DEFAULT_COST); // needs to be less than competing nodes 10105 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 10106 10107 ins_encode %{ 10108 bool success = false; 10109 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 10110 if (InlineSecondarySupersTest) { 10111 success = __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $result$$Register, 10112 $tmpR11$$Register, $tmpR12$$Register, $tmpR13$$Register, 10113 $tmpR16$$Register, super_klass_slot); 10114 } else { 10115 address call = __ reloc_call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 10116 success = (call != nullptr); 10117 } 10118 if (!success) { 10119 ciEnv::current()->record_failure("CodeCache is full"); 10120 return; 10121 } 10122 %} 10123 10124 ins_pipe(pipe_class_memory); 10125 %} 10126 10127 instruct partialSubtypeCheckVsZero(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, 10128 immP0 zero, rFlagsReg cr) 10129 %{ 10130 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 10131 effect(KILL tmp, KILL result); 10132 10133 ins_cost(11 * DEFAULT_COST); 10134 format %{ "partialSubtypeCheck $result, $sub, $super == 0\t#@partialSubtypeCheckVsZero" %} 10135 10136 ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); 10137 10138 opcode(0x0); // Don't zero result reg on hit 10139 10140 ins_pipe(pipe_class_memory); 10141 %} 10142 10143 instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10144 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 10145 %{ 10146 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU); 10147 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10148 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10149 10150 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %} 10151 ins_encode %{ 10152 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 10153 __ string_compare($str1$$Register, $str2$$Register, 10154 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10155 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10156 StrIntrinsicNode::UU); 10157 %} 10158 ins_pipe(pipe_class_memory); 10159 %} 10160 10161 instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10162 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 10163 %{ 10164 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL); 10165 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10166 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10167 10168 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %} 10169 ins_encode %{ 10170 __ string_compare($str1$$Register, $str2$$Register, 10171 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10172 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10173 StrIntrinsicNode::LL); 10174 %} 10175 ins_pipe(pipe_class_memory); 10176 %} 10177 10178 instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10179 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 10180 %{ 10181 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL); 10182 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10183 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10184 10185 format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %} 10186 ins_encode %{ 10187 __ string_compare($str1$$Register, $str2$$Register, 10188 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10189 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10190 StrIntrinsicNode::UL); 10191 %} 10192 ins_pipe(pipe_class_memory); 10193 %} 10194 10195 instruct string_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10196 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, 10197 rFlagsReg cr) 10198 %{ 10199 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU); 10200 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10201 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10202 10203 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %} 10204 ins_encode %{ 10205 __ string_compare($str1$$Register, $str2$$Register, 10206 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10207 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10208 StrIntrinsicNode::LU); 10209 %} 10210 ins_pipe(pipe_class_memory); 10211 %} 10212 10213 instruct string_indexofUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10214 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 10215 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 10216 %{ 10217 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 10218 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10219 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 10220 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 10221 10222 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 10223 ins_encode %{ 10224 __ string_indexof($str1$$Register, $str2$$Register, 10225 $cnt1$$Register, $cnt2$$Register, 10226 $tmp1$$Register, $tmp2$$Register, 10227 $tmp3$$Register, $tmp4$$Register, 10228 $tmp5$$Register, $tmp6$$Register, 10229 $result$$Register, StrIntrinsicNode::UU); 10230 %} 10231 ins_pipe(pipe_class_memory); 10232 %} 10233 10234 instruct string_indexofLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10235 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 10236 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 10237 %{ 10238 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 10239 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10240 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 10241 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 10242 10243 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 10244 ins_encode %{ 10245 __ string_indexof($str1$$Register, $str2$$Register, 10246 $cnt1$$Register, $cnt2$$Register, 10247 $tmp1$$Register, $tmp2$$Register, 10248 $tmp3$$Register, $tmp4$$Register, 10249 $tmp5$$Register, $tmp6$$Register, 10250 $result$$Register, StrIntrinsicNode::LL); 10251 %} 10252 ins_pipe(pipe_class_memory); 10253 %} 10254 10255 instruct string_indexofUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 10256 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 10257 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 10258 %{ 10259 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 10260 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10261 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 10262 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 10263 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 10264 10265 ins_encode %{ 10266 __ string_indexof($str1$$Register, $str2$$Register, 10267 $cnt1$$Register, $cnt2$$Register, 10268 $tmp1$$Register, $tmp2$$Register, 10269 $tmp3$$Register, $tmp4$$Register, 10270 $tmp5$$Register, $tmp6$$Register, 10271 $result$$Register, StrIntrinsicNode::UL); 10272 %} 10273 ins_pipe(pipe_class_memory); 10274 %} 10275 10276 instruct string_indexof_conUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 10277 immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10278 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10279 %{ 10280 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 10281 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10282 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 10283 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10284 10285 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 10286 10287 ins_encode %{ 10288 int icnt2 = (int)$int_cnt2$$constant; 10289 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10290 $cnt1$$Register, zr, 10291 $tmp1$$Register, $tmp2$$Register, 10292 $tmp3$$Register, $tmp4$$Register, 10293 icnt2, $result$$Register, StrIntrinsicNode::UU); 10294 %} 10295 ins_pipe(pipe_class_memory); 10296 %} 10297 10298 instruct string_indexof_conLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 10299 immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10300 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10301 %{ 10302 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 10303 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10304 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 10305 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10306 10307 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 10308 ins_encode %{ 10309 int icnt2 = (int)$int_cnt2$$constant; 10310 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10311 $cnt1$$Register, zr, 10312 $tmp1$$Register, $tmp2$$Register, 10313 $tmp3$$Register, $tmp4$$Register, 10314 icnt2, $result$$Register, StrIntrinsicNode::LL); 10315 %} 10316 ins_pipe(pipe_class_memory); 10317 %} 10318 10319 instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 10320 immI_1 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10321 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10322 %{ 10323 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 10324 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10325 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 10326 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10327 10328 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 10329 ins_encode %{ 10330 int icnt2 = (int)$int_cnt2$$constant; 10331 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10332 $cnt1$$Register, zr, 10333 $tmp1$$Register, $tmp2$$Register, 10334 $tmp3$$Register, $tmp4$$Register, 10335 icnt2, $result$$Register, StrIntrinsicNode::UL); 10336 %} 10337 ins_pipe(pipe_class_memory); 10338 %} 10339 10340 instruct stringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, 10341 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10342 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10343 %{ 10344 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10345 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10346 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, 10347 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10348 10349 format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %} 10350 ins_encode %{ 10351 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 10352 $result$$Register, $tmp1$$Register, $tmp2$$Register, 10353 $tmp3$$Register, $tmp4$$Register, false /* isU */); 10354 %} 10355 ins_pipe(pipe_class_memory); 10356 %} 10357 10358 10359 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, 10360 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10361 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10362 %{ 10363 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10364 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10365 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, 10366 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10367 10368 format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %} 10369 ins_encode %{ 10370 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 10371 $result$$Register, $tmp1$$Register, $tmp2$$Register, 10372 $tmp3$$Register, $tmp4$$Register, true /* isL */); 10373 %} 10374 ins_pipe(pipe_class_memory); 10375 %} 10376 10377 // clearing of an array 10378 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegP_R30 tmp1, 10379 iRegP_R31 tmp2, Universe dummy) 10380 %{ 10381 // temp registers must match the one used in StubGenerator::generate_zero_blocks() 10382 predicate(UseBlockZeroing || !UseRVV); 10383 match(Set dummy (ClearArray cnt base)); 10384 effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2); 10385 10386 ins_cost(4 * DEFAULT_COST); 10387 format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %} 10388 10389 ins_encode %{ 10390 address tpc = __ zero_words($base$$Register, $cnt$$Register); 10391 if (tpc == nullptr) { 10392 ciEnv::current()->record_failure("CodeCache is full"); 10393 return; 10394 } 10395 %} 10396 10397 ins_pipe(pipe_class_memory); 10398 %} 10399 10400 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr) 10401 %{ 10402 predicate(!UseRVV && (uint64_t)n->in(2)->get_long() 10403 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 10404 match(Set dummy (ClearArray cnt base)); 10405 effect(USE_KILL base, KILL cr); 10406 10407 ins_cost(4 * DEFAULT_COST); 10408 format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %} 10409 10410 ins_encode %{ 10411 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 10412 %} 10413 10414 ins_pipe(pipe_class_memory); 10415 %} 10416 10417 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, 10418 iRegI_R10 result, rFlagsReg cr) 10419 %{ 10420 predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 10421 match(Set result (StrEquals (Binary str1 str2) cnt)); 10422 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 10423 10424 format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %} 10425 ins_encode %{ 10426 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 10427 __ string_equals($str1$$Register, $str2$$Register, 10428 $result$$Register, $cnt$$Register); 10429 %} 10430 ins_pipe(pipe_class_memory); 10431 %} 10432 10433 instruct array_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, 10434 iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3) 10435 %{ 10436 predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10437 match(Set result (AryEq ary1 ary2)); 10438 effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3); 10439 10440 format %{ "Array Equals $ary1, $ary2 -> $result\t#@array_equalsB // KILL all" %} 10441 ins_encode %{ 10442 __ arrays_equals($ary1$$Register, $ary2$$Register, 10443 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10444 $result$$Register, 1); 10445 %} 10446 ins_pipe(pipe_class_memory); 10447 %} 10448 10449 instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, 10450 iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3) 10451 %{ 10452 predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10453 match(Set result (AryEq ary1 ary2)); 10454 effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3); 10455 10456 format %{ "Array Equals $ary1, $ary2 -> $result\t#@array_equalsC // KILL all" %} 10457 ins_encode %{ 10458 __ arrays_equals($ary1$$Register, $ary2$$Register, 10459 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10460 $result$$Register, 2); 10461 %} 10462 ins_pipe(pipe_class_memory); 10463 %} 10464 10465 // fast ArraysSupport.vectorizedHashCode 10466 instruct arrays_hashcode(iRegP_R11 ary, iRegI_R12 cnt, iRegI_R10 result, immI basic_type, 10467 iRegLNoSp tmp1, iRegLNoSp tmp2, 10468 iRegLNoSp tmp3, iRegLNoSp tmp4, 10469 iRegLNoSp tmp5, iRegLNoSp tmp6, rFlagsReg cr) 10470 %{ 10471 match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type))); 10472 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 10473 USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr); 10474 10475 format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result // KILL all" %} 10476 ins_encode %{ 10477 __ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register, 10478 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 10479 $tmp4$$Register, $tmp5$$Register, $tmp6$$Register, 10480 (BasicType)$basic_type$$constant); 10481 %} 10482 ins_pipe(pipe_class_memory); 10483 %} 10484 10485 // ============================================================================ 10486 // Safepoint Instructions 10487 10488 instruct safePoint(iRegP poll) 10489 %{ 10490 match(SafePoint poll); 10491 10492 ins_cost(2 * LOAD_COST); 10493 format %{ 10494 "lwu zr, [$poll]\t# Safepoint: poll for GC, #@safePoint" 10495 %} 10496 ins_encode %{ 10497 __ read_polling_page(as_Register($poll$$reg), 0, relocInfo::poll_type); 10498 %} 10499 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 10500 %} 10501 10502 // ============================================================================ 10503 // This name is KNOWN by the ADLC and cannot be changed. 10504 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 10505 // for this guy. 10506 instruct tlsLoadP(javaThread_RegP dst) 10507 %{ 10508 match(Set dst (ThreadLocal)); 10509 10510 ins_cost(0); 10511 10512 format %{ " -- \t// $dst=Thread::current(), empty, #@tlsLoadP" %} 10513 10514 size(0); 10515 10516 ins_encode( /*empty*/ ); 10517 10518 ins_pipe(pipe_class_empty); 10519 %} 10520 10521 // inlined locking and unlocking 10522 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers 10523 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3) 10524 %{ 10525 predicate(LockingMode != LM_LIGHTWEIGHT); 10526 match(Set cr (FastLock object box)); 10527 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 10528 10529 ins_cost(10 * DEFAULT_COST); 10530 format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3, #@cmpFastLock" %} 10531 10532 ins_encode %{ 10533 __ fast_lock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 10534 %} 10535 10536 ins_pipe(pipe_serial); 10537 %} 10538 10539 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers 10540 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) 10541 %{ 10542 predicate(LockingMode != LM_LIGHTWEIGHT); 10543 match(Set cr (FastUnlock object box)); 10544 effect(TEMP tmp1, TEMP tmp2); 10545 10546 ins_cost(10 * DEFAULT_COST); 10547 format %{ "fastunlock $object,$box\t! kills $tmp1, $tmp2, #@cmpFastUnlock" %} 10548 10549 ins_encode %{ 10550 __ fast_unlock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register); 10551 %} 10552 10553 ins_pipe(pipe_serial); 10554 %} 10555 10556 instruct cmpFastLockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3) 10557 %{ 10558 predicate(LockingMode == LM_LIGHTWEIGHT); 10559 match(Set cr (FastLock object box)); 10560 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 10561 10562 ins_cost(10 * DEFAULT_COST); 10563 format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3 #@cmpFastLockLightweight" %} 10564 10565 ins_encode %{ 10566 __ fast_lock_lightweight($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 10567 %} 10568 10569 ins_pipe(pipe_serial); 10570 %} 10571 10572 instruct cmpFastUnlockLightweight(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3) 10573 %{ 10574 predicate(LockingMode == LM_LIGHTWEIGHT); 10575 match(Set cr (FastUnlock object box)); 10576 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 10577 10578 ins_cost(10 * DEFAULT_COST); 10579 format %{ "fastunlock $object,$box\t! kills $tmp1,$tmp2,$tmp3 #@cmpFastUnlockLightweight" %} 10580 10581 ins_encode %{ 10582 __ fast_unlock_lightweight($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 10583 %} 10584 10585 ins_pipe(pipe_serial); 10586 %} 10587 10588 // Tail Call; Jump from runtime stub to Java code. 10589 // Also known as an 'interprocedural jump'. 10590 // Target of jump will eventually return to caller. 10591 // TailJump below removes the return address. 10592 // Don't use fp for 'jump_target' because a MachEpilogNode has already been 10593 // emitted just above the TailCall which has reset fp to the caller state. 10594 instruct TailCalljmpInd(iRegPNoSpNoFp jump_target, inline_cache_RegP method_oop) 10595 %{ 10596 match(TailCall jump_target method_oop); 10597 10598 ins_cost(BRANCH_COST); 10599 10600 format %{ "jalr $jump_target\t# $method_oop holds method oop, #@TailCalljmpInd." %} 10601 10602 ins_encode(riscv_enc_tail_call(jump_target)); 10603 10604 ins_pipe(pipe_class_call); 10605 %} 10606 10607 instruct TailjmpInd(iRegPNoSpNoFp jump_target, iRegP_R10 ex_oop) 10608 %{ 10609 match(TailJump jump_target ex_oop); 10610 10611 ins_cost(ALU_COST + BRANCH_COST); 10612 10613 format %{ "jalr $jump_target\t# $ex_oop holds exception oop, #@TailjmpInd." %} 10614 10615 ins_encode(riscv_enc_tail_jmp(jump_target)); 10616 10617 ins_pipe(pipe_class_call); 10618 %} 10619 10620 // Forward exception. 10621 instruct ForwardExceptionjmp() 10622 %{ 10623 match(ForwardException); 10624 10625 ins_cost(BRANCH_COST); 10626 10627 format %{ "j forward_exception_stub\t#@ForwardException" %} 10628 10629 ins_encode %{ 10630 __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); 10631 %} 10632 10633 ins_pipe(pipe_class_call); 10634 %} 10635 10636 // Create exception oop: created by stack-crawling runtime code. 10637 // Created exception is now available to this handler, and is setup 10638 // just prior to jumping to this handler. No code emitted. 10639 instruct CreateException(iRegP_R10 ex_oop) 10640 %{ 10641 match(Set ex_oop (CreateEx)); 10642 10643 ins_cost(0); 10644 format %{ " -- \t// exception oop; no code emitted, #@CreateException" %} 10645 10646 size(0); 10647 10648 ins_encode( /*empty*/ ); 10649 10650 ins_pipe(pipe_class_empty); 10651 %} 10652 10653 // Rethrow exception: The exception oop will come in the first 10654 // argument position. Then JUMP (not call) to the rethrow stub code. 10655 instruct RethrowException() 10656 %{ 10657 match(Rethrow); 10658 10659 ins_cost(BRANCH_COST); 10660 10661 format %{ "j rethrow_stub\t#@RethrowException" %} 10662 10663 ins_encode(riscv_enc_rethrow()); 10664 10665 ins_pipe(pipe_class_call); 10666 %} 10667 10668 // Return Instruction 10669 // epilog node loads ret address into ra as part of frame pop 10670 instruct Ret() 10671 %{ 10672 match(Return); 10673 10674 ins_cost(BRANCH_COST); 10675 format %{ "ret\t// return register, #@Ret" %} 10676 10677 ins_encode(riscv_enc_ret()); 10678 10679 ins_pipe(pipe_branch); 10680 %} 10681 10682 // Die now. 10683 instruct ShouldNotReachHere() %{ 10684 match(Halt); 10685 10686 ins_cost(BRANCH_COST); 10687 10688 format %{ "#@ShouldNotReachHere" %} 10689 10690 ins_encode %{ 10691 if (is_reachable()) { 10692 __ stop(_halt_reason); 10693 } 10694 %} 10695 10696 ins_pipe(pipe_class_default); 10697 %} 10698 10699 10700 //----------PEEPHOLE RULES----------------------------------------------------- 10701 // These must follow all instruction definitions as they use the names 10702 // defined in the instructions definitions. 10703 // 10704 // peepmatch ( root_instr_name [preceding_instruction]* ); 10705 // 10706 // peepconstraint %{ 10707 // (instruction_number.operand_name relational_op instruction_number.operand_name 10708 // [, ...] ); 10709 // // instruction numbers are zero-based using left to right order in peepmatch 10710 // 10711 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 10712 // // provide an instruction_number.operand_name for each operand that appears 10713 // // in the replacement instruction's match rule 10714 // 10715 // ---------VM FLAGS--------------------------------------------------------- 10716 // 10717 // All peephole optimizations can be turned off using -XX:-OptoPeephole 10718 // 10719 // Each peephole rule is given an identifying number starting with zero and 10720 // increasing by one in the order seen by the parser. An individual peephole 10721 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 10722 // on the command-line. 10723 // 10724 // ---------CURRENT LIMITATIONS---------------------------------------------- 10725 // 10726 // Only match adjacent instructions in same basic block 10727 // Only equality constraints 10728 // Only constraints between operands, not (0.dest_reg == RAX_enc) 10729 // Only one replacement instruction 10730 // 10731 //----------SMARTSPILL RULES--------------------------------------------------- 10732 // These must follow all instruction definitions as they use the names 10733 // defined in the instructions definitions. 10734 10735 // Local Variables: 10736 // mode: c++ 10737 // End: