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