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