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, NS, Op_RegI, 2, x2->as_VMReg() ); // sp 88 reg_def R2_H ( NS, NS, Op_RegI, 2, x2->as_VMReg()->next() ); 89 reg_def R3 ( NS, NS, Op_RegI, 3, x3->as_VMReg() ); // gp 90 reg_def R3_H ( NS, NS, Op_RegI, 3, x3->as_VMReg()->next() ); 91 reg_def R4 ( NS, NS, Op_RegI, 4, x4->as_VMReg() ); // tp 92 reg_def R4_H ( NS, NS, Op_RegI, 4, x4->as_VMReg()->next() ); 93 reg_def R7 ( SOC, SOC, Op_RegI, 7, x7->as_VMReg() ); 94 reg_def R7_H ( SOC, SOC, Op_RegI, 7, x7->as_VMReg()->next() ); 95 reg_def R8 ( NS, SOE, Op_RegI, 8, x8->as_VMReg() ); // fp 96 reg_def R8_H ( NS, SOE, Op_RegI, 8, x8->as_VMReg()->next() ); 97 reg_def R9 ( SOC, SOE, Op_RegI, 9, x9->as_VMReg() ); 98 reg_def R9_H ( SOC, SOE, Op_RegI, 9, x9->as_VMReg()->next() ); 99 reg_def R10 ( SOC, SOC, Op_RegI, 10, x10->as_VMReg() ); 100 reg_def R10_H ( SOC, SOC, Op_RegI, 10, x10->as_VMReg()->next()); 101 reg_def R11 ( SOC, SOC, Op_RegI, 11, x11->as_VMReg() ); 102 reg_def R11_H ( SOC, SOC, Op_RegI, 11, x11->as_VMReg()->next()); 103 reg_def R12 ( SOC, SOC, Op_RegI, 12, x12->as_VMReg() ); 104 reg_def R12_H ( SOC, SOC, Op_RegI, 12, x12->as_VMReg()->next()); 105 reg_def R13 ( SOC, SOC, Op_RegI, 13, x13->as_VMReg() ); 106 reg_def R13_H ( SOC, SOC, Op_RegI, 13, x13->as_VMReg()->next()); 107 reg_def R14 ( SOC, SOC, Op_RegI, 14, x14->as_VMReg() ); 108 reg_def R14_H ( SOC, SOC, Op_RegI, 14, x14->as_VMReg()->next()); 109 reg_def R15 ( SOC, SOC, Op_RegI, 15, x15->as_VMReg() ); 110 reg_def R15_H ( SOC, SOC, Op_RegI, 15, x15->as_VMReg()->next()); 111 reg_def R16 ( SOC, SOC, Op_RegI, 16, x16->as_VMReg() ); 112 reg_def R16_H ( SOC, SOC, Op_RegI, 16, x16->as_VMReg()->next()); 113 reg_def R17 ( SOC, SOC, Op_RegI, 17, x17->as_VMReg() ); 114 reg_def R17_H ( SOC, SOC, Op_RegI, 17, x17->as_VMReg()->next()); 115 reg_def R18 ( SOC, SOE, Op_RegI, 18, x18->as_VMReg() ); 116 reg_def R18_H ( SOC, SOE, Op_RegI, 18, x18->as_VMReg()->next()); 117 reg_def R19 ( SOC, SOE, Op_RegI, 19, x19->as_VMReg() ); 118 reg_def R19_H ( SOC, SOE, Op_RegI, 19, x19->as_VMReg()->next()); 119 reg_def R20 ( SOC, SOE, Op_RegI, 20, x20->as_VMReg() ); // caller esp 120 reg_def R20_H ( SOC, SOE, Op_RegI, 20, x20->as_VMReg()->next()); 121 reg_def R21 ( SOC, SOE, Op_RegI, 21, x21->as_VMReg() ); 122 reg_def R21_H ( SOC, SOE, Op_RegI, 21, x21->as_VMReg()->next()); 123 reg_def R22 ( SOC, SOE, Op_RegI, 22, x22->as_VMReg() ); 124 reg_def R22_H ( SOC, SOE, Op_RegI, 22, x22->as_VMReg()->next()); 125 reg_def R23 ( NS, SOE, Op_RegI, 23, x23->as_VMReg() ); // java thread 126 reg_def R23_H ( NS, SOE, Op_RegI, 23, x23->as_VMReg()->next()); 127 reg_def R24 ( SOC, SOE, Op_RegI, 24, x24->as_VMReg() ); 128 reg_def R24_H ( SOC, SOE, Op_RegI, 24, x24->as_VMReg()->next()); 129 reg_def R25 ( SOC, SOE, Op_RegI, 25, x25->as_VMReg() ); 130 reg_def R25_H ( SOC, SOE, Op_RegI, 25, x25->as_VMReg()->next()); 131 reg_def R26 ( SOC, SOE, Op_RegI, 26, x26->as_VMReg() ); 132 reg_def R26_H ( SOC, SOE, Op_RegI, 26, x26->as_VMReg()->next()); 133 reg_def R27 ( SOC, SOE, Op_RegI, 27, x27->as_VMReg() ); // heapbase 134 reg_def R27_H ( SOC, SOE, Op_RegI, 27, x27->as_VMReg()->next()); 135 reg_def R28 ( SOC, SOC, Op_RegI, 28, x28->as_VMReg() ); 136 reg_def R28_H ( SOC, SOC, Op_RegI, 28, x28->as_VMReg()->next()); 137 reg_def R29 ( SOC, SOC, Op_RegI, 29, x29->as_VMReg() ); 138 reg_def R29_H ( SOC, SOC, Op_RegI, 29, x29->as_VMReg()->next()); 139 reg_def R30 ( SOC, SOC, Op_RegI, 30, x30->as_VMReg() ); 140 reg_def R30_H ( SOC, SOC, Op_RegI, 30, x30->as_VMReg()->next()); 141 reg_def R31 ( SOC, SOC, Op_RegI, 31, x31->as_VMReg() ); 142 reg_def R31_H ( SOC, SOC, Op_RegI, 31, x31->as_VMReg()->next()); 143 144 // ---------------------------- 145 // Float/Double Registers 146 // ---------------------------- 147 148 // Double Registers 149 150 // The rules of ADL require that double registers be defined in pairs. 151 // Each pair must be two 32-bit values, but not necessarily a pair of 152 // single float registers. In each pair, ADLC-assigned register numbers 153 // must be adjacent, with the lower number even. Finally, when the 154 // CPU stores such a register pair to memory, the word associated with 155 // the lower ADLC-assigned number must be stored to the lower address. 156 157 // RISCV has 32 floating-point registers. Each can store a single 158 // or double precision floating-point value. 159 160 // for Java use float registers f0-f31 are always save on call whereas 161 // the platform ABI treats f8-f9 and f18-f27 as callee save). Other 162 // float registers are SOC as per the platform spec 163 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, f0->as_VMReg() ); 165 reg_def F0_H ( SOC, SOC, Op_RegF, 0, f0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, f1->as_VMReg() ); 167 reg_def F1_H ( SOC, SOC, Op_RegF, 1, f1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, f2->as_VMReg() ); 169 reg_def F2_H ( SOC, SOC, Op_RegF, 2, f2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, f3->as_VMReg() ); 171 reg_def F3_H ( SOC, SOC, Op_RegF, 3, f3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, f4->as_VMReg() ); 173 reg_def F4_H ( SOC, SOC, Op_RegF, 4, f4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, f5->as_VMReg() ); 175 reg_def F5_H ( SOC, SOC, Op_RegF, 5, f5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, f6->as_VMReg() ); 177 reg_def F6_H ( SOC, SOC, Op_RegF, 6, f6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, f7->as_VMReg() ); 179 reg_def F7_H ( SOC, SOC, Op_RegF, 7, f7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOE, Op_RegF, 8, f8->as_VMReg() ); 181 reg_def F8_H ( SOC, SOE, Op_RegF, 8, f8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOE, Op_RegF, 9, f9->as_VMReg() ); 183 reg_def F9_H ( SOC, SOE, Op_RegF, 9, f9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, f10->as_VMReg() ); 185 reg_def F10_H ( SOC, SOC, Op_RegF, 10, f10->as_VMReg()->next() ); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, f11->as_VMReg() ); 187 reg_def F11_H ( SOC, SOC, Op_RegF, 11, f11->as_VMReg()->next() ); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, f12->as_VMReg() ); 189 reg_def F12_H ( SOC, SOC, Op_RegF, 12, f12->as_VMReg()->next() ); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, f13->as_VMReg() ); 191 reg_def F13_H ( SOC, SOC, Op_RegF, 13, f13->as_VMReg()->next() ); 192 reg_def F14 ( SOC, SOC, Op_RegF, 14, f14->as_VMReg() ); 193 reg_def F14_H ( SOC, SOC, Op_RegF, 14, f14->as_VMReg()->next() ); 194 reg_def F15 ( SOC, SOC, Op_RegF, 15, f15->as_VMReg() ); 195 reg_def F15_H ( SOC, SOC, Op_RegF, 15, f15->as_VMReg()->next() ); 196 reg_def F16 ( SOC, SOC, Op_RegF, 16, f16->as_VMReg() ); 197 reg_def F16_H ( SOC, SOC, Op_RegF, 16, f16->as_VMReg()->next() ); 198 reg_def F17 ( SOC, SOC, Op_RegF, 17, f17->as_VMReg() ); 199 reg_def F17_H ( SOC, SOC, Op_RegF, 17, f17->as_VMReg()->next() ); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, f18->as_VMReg() ); 201 reg_def F18_H ( SOC, SOE, Op_RegF, 18, f18->as_VMReg()->next() ); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, f19->as_VMReg() ); 203 reg_def F19_H ( SOC, SOE, Op_RegF, 19, f19->as_VMReg()->next() ); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, f20->as_VMReg() ); 205 reg_def F20_H ( SOC, SOE, Op_RegF, 20, f20->as_VMReg()->next() ); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, f21->as_VMReg() ); 207 reg_def F21_H ( SOC, SOE, Op_RegF, 21, f21->as_VMReg()->next() ); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, f22->as_VMReg() ); 209 reg_def F22_H ( SOC, SOE, Op_RegF, 22, f22->as_VMReg()->next() ); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, f23->as_VMReg() ); 211 reg_def F23_H ( SOC, SOE, Op_RegF, 23, f23->as_VMReg()->next() ); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, f24->as_VMReg() ); 213 reg_def F24_H ( SOC, SOE, Op_RegF, 24, f24->as_VMReg()->next() ); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, f25->as_VMReg() ); 215 reg_def F25_H ( SOC, SOE, Op_RegF, 25, f25->as_VMReg()->next() ); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, f26->as_VMReg() ); 217 reg_def F26_H ( SOC, SOE, Op_RegF, 26, f26->as_VMReg()->next() ); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, f27->as_VMReg() ); 219 reg_def F27_H ( SOC, SOE, Op_RegF, 27, f27->as_VMReg()->next() ); 220 reg_def F28 ( SOC, SOC, Op_RegF, 28, f28->as_VMReg() ); 221 reg_def F28_H ( SOC, SOC, Op_RegF, 28, f28->as_VMReg()->next() ); 222 reg_def F29 ( SOC, SOC, Op_RegF, 29, f29->as_VMReg() ); 223 reg_def F29_H ( SOC, SOC, Op_RegF, 29, f29->as_VMReg()->next() ); 224 reg_def F30 ( SOC, SOC, Op_RegF, 30, f30->as_VMReg() ); 225 reg_def F30_H ( SOC, SOC, Op_RegF, 30, f30->as_VMReg()->next() ); 226 reg_def F31 ( SOC, SOC, Op_RegF, 31, f31->as_VMReg() ); 227 reg_def F31_H ( SOC, SOC, Op_RegF, 31, f31->as_VMReg()->next() ); 228 229 // ---------------------------- 230 // Vector Registers 231 // ---------------------------- 232 233 // For RVV vector registers, we simply extend vector register size to 4 234 // 'logical' slots. This is nominally 128 bits but it actually covers 235 // all possible 'physical' RVV vector register lengths from 128 ~ 1024 236 // bits. The 'physical' RVV vector register length is detected during 237 // startup, so the register allocator is able to identify the correct 238 // number of bytes needed for an RVV spill/unspill. 239 240 reg_def V0 ( SOC, SOC, Op_VecA, 0, v0->as_VMReg() ); 241 reg_def V0_H ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next() ); 242 reg_def V0_J ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(2) ); 243 reg_def V0_K ( SOC, SOC, Op_VecA, 0, v0->as_VMReg()->next(3) ); 244 245 reg_def V1 ( SOC, SOC, Op_VecA, 1, v1->as_VMReg() ); 246 reg_def V1_H ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next() ); 247 reg_def V1_J ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(2) ); 248 reg_def V1_K ( SOC, SOC, Op_VecA, 1, v1->as_VMReg()->next(3) ); 249 250 reg_def V2 ( SOC, SOC, Op_VecA, 2, v2->as_VMReg() ); 251 reg_def V2_H ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next() ); 252 reg_def V2_J ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(2) ); 253 reg_def V2_K ( SOC, SOC, Op_VecA, 2, v2->as_VMReg()->next(3) ); 254 255 reg_def V3 ( SOC, SOC, Op_VecA, 3, v3->as_VMReg() ); 256 reg_def V3_H ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next() ); 257 reg_def V3_J ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(2) ); 258 reg_def V3_K ( SOC, SOC, Op_VecA, 3, v3->as_VMReg()->next(3) ); 259 260 reg_def V4 ( SOC, SOC, Op_VecA, 4, v4->as_VMReg() ); 261 reg_def V4_H ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next() ); 262 reg_def V4_J ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(2) ); 263 reg_def V4_K ( SOC, SOC, Op_VecA, 4, v4->as_VMReg()->next(3) ); 264 265 reg_def V5 ( SOC, SOC, Op_VecA, 5, v5->as_VMReg() ); 266 reg_def V5_H ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next() ); 267 reg_def V5_J ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(2) ); 268 reg_def V5_K ( SOC, SOC, Op_VecA, 5, v5->as_VMReg()->next(3) ); 269 270 reg_def V6 ( SOC, SOC, Op_VecA, 6, v6->as_VMReg() ); 271 reg_def V6_H ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next() ); 272 reg_def V6_J ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(2) ); 273 reg_def V6_K ( SOC, SOC, Op_VecA, 6, v6->as_VMReg()->next(3) ); 274 275 reg_def V7 ( SOC, SOC, Op_VecA, 7, v7->as_VMReg() ); 276 reg_def V7_H ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next() ); 277 reg_def V7_J ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(2) ); 278 reg_def V7_K ( SOC, SOC, Op_VecA, 7, v7->as_VMReg()->next(3) ); 279 280 reg_def V8 ( SOC, SOC, Op_VecA, 8, v8->as_VMReg() ); 281 reg_def V8_H ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next() ); 282 reg_def V8_J ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(2) ); 283 reg_def V8_K ( SOC, SOC, Op_VecA, 8, v8->as_VMReg()->next(3) ); 284 285 reg_def V9 ( SOC, SOC, Op_VecA, 9, v9->as_VMReg() ); 286 reg_def V9_H ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next() ); 287 reg_def V9_J ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(2) ); 288 reg_def V9_K ( SOC, SOC, Op_VecA, 9, v9->as_VMReg()->next(3) ); 289 290 reg_def V10 ( SOC, SOC, Op_VecA, 10, v10->as_VMReg() ); 291 reg_def V10_H ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next() ); 292 reg_def V10_J ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(2) ); 293 reg_def V10_K ( SOC, SOC, Op_VecA, 10, v10->as_VMReg()->next(3) ); 294 295 reg_def V11 ( SOC, SOC, Op_VecA, 11, v11->as_VMReg() ); 296 reg_def V11_H ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next() ); 297 reg_def V11_J ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(2) ); 298 reg_def V11_K ( SOC, SOC, Op_VecA, 11, v11->as_VMReg()->next(3) ); 299 300 reg_def V12 ( SOC, SOC, Op_VecA, 12, v12->as_VMReg() ); 301 reg_def V12_H ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next() ); 302 reg_def V12_J ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(2) ); 303 reg_def V12_K ( SOC, SOC, Op_VecA, 12, v12->as_VMReg()->next(3) ); 304 305 reg_def V13 ( SOC, SOC, Op_VecA, 13, v13->as_VMReg() ); 306 reg_def V13_H ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next() ); 307 reg_def V13_J ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(2) ); 308 reg_def V13_K ( SOC, SOC, Op_VecA, 13, v13->as_VMReg()->next(3) ); 309 310 reg_def V14 ( SOC, SOC, Op_VecA, 14, v14->as_VMReg() ); 311 reg_def V14_H ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next() ); 312 reg_def V14_J ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(2) ); 313 reg_def V14_K ( SOC, SOC, Op_VecA, 14, v14->as_VMReg()->next(3) ); 314 315 reg_def V15 ( SOC, SOC, Op_VecA, 15, v15->as_VMReg() ); 316 reg_def V15_H ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next() ); 317 reg_def V15_J ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(2) ); 318 reg_def V15_K ( SOC, SOC, Op_VecA, 15, v15->as_VMReg()->next(3) ); 319 320 reg_def V16 ( SOC, SOC, Op_VecA, 16, v16->as_VMReg() ); 321 reg_def V16_H ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next() ); 322 reg_def V16_J ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(2) ); 323 reg_def V16_K ( SOC, SOC, Op_VecA, 16, v16->as_VMReg()->next(3) ); 324 325 reg_def V17 ( SOC, SOC, Op_VecA, 17, v17->as_VMReg() ); 326 reg_def V17_H ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next() ); 327 reg_def V17_J ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(2) ); 328 reg_def V17_K ( SOC, SOC, Op_VecA, 17, v17->as_VMReg()->next(3) ); 329 330 reg_def V18 ( SOC, SOC, Op_VecA, 18, v18->as_VMReg() ); 331 reg_def V18_H ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next() ); 332 reg_def V18_J ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(2) ); 333 reg_def V18_K ( SOC, SOC, Op_VecA, 18, v18->as_VMReg()->next(3) ); 334 335 reg_def V19 ( SOC, SOC, Op_VecA, 19, v19->as_VMReg() ); 336 reg_def V19_H ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next() ); 337 reg_def V19_J ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(2) ); 338 reg_def V19_K ( SOC, SOC, Op_VecA, 19, v19->as_VMReg()->next(3) ); 339 340 reg_def V20 ( SOC, SOC, Op_VecA, 20, v20->as_VMReg() ); 341 reg_def V20_H ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next() ); 342 reg_def V20_J ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(2) ); 343 reg_def V20_K ( SOC, SOC, Op_VecA, 20, v20->as_VMReg()->next(3) ); 344 345 reg_def V21 ( SOC, SOC, Op_VecA, 21, v21->as_VMReg() ); 346 reg_def V21_H ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next() ); 347 reg_def V21_J ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(2) ); 348 reg_def V21_K ( SOC, SOC, Op_VecA, 21, v21->as_VMReg()->next(3) ); 349 350 reg_def V22 ( SOC, SOC, Op_VecA, 22, v22->as_VMReg() ); 351 reg_def V22_H ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next() ); 352 reg_def V22_J ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(2) ); 353 reg_def V22_K ( SOC, SOC, Op_VecA, 22, v22->as_VMReg()->next(3) ); 354 355 reg_def V23 ( SOC, SOC, Op_VecA, 23, v23->as_VMReg() ); 356 reg_def V23_H ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next() ); 357 reg_def V23_J ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(2) ); 358 reg_def V23_K ( SOC, SOC, Op_VecA, 23, v23->as_VMReg()->next(3) ); 359 360 reg_def V24 ( SOC, SOC, Op_VecA, 24, v24->as_VMReg() ); 361 reg_def V24_H ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next() ); 362 reg_def V24_J ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(2) ); 363 reg_def V24_K ( SOC, SOC, Op_VecA, 24, v24->as_VMReg()->next(3) ); 364 365 reg_def V25 ( SOC, SOC, Op_VecA, 25, v25->as_VMReg() ); 366 reg_def V25_H ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next() ); 367 reg_def V25_J ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(2) ); 368 reg_def V25_K ( SOC, SOC, Op_VecA, 25, v25->as_VMReg()->next(3) ); 369 370 reg_def V26 ( SOC, SOC, Op_VecA, 26, v26->as_VMReg() ); 371 reg_def V26_H ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next() ); 372 reg_def V26_J ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(2) ); 373 reg_def V26_K ( SOC, SOC, Op_VecA, 26, v26->as_VMReg()->next(3) ); 374 375 reg_def V27 ( SOC, SOC, Op_VecA, 27, v27->as_VMReg() ); 376 reg_def V27_H ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next() ); 377 reg_def V27_J ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(2) ); 378 reg_def V27_K ( SOC, SOC, Op_VecA, 27, v27->as_VMReg()->next(3) ); 379 380 reg_def V28 ( SOC, SOC, Op_VecA, 28, v28->as_VMReg() ); 381 reg_def V28_H ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next() ); 382 reg_def V28_J ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(2) ); 383 reg_def V28_K ( SOC, SOC, Op_VecA, 28, v28->as_VMReg()->next(3) ); 384 385 reg_def V29 ( SOC, SOC, Op_VecA, 29, v29->as_VMReg() ); 386 reg_def V29_H ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next() ); 387 reg_def V29_J ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(2) ); 388 reg_def V29_K ( SOC, SOC, Op_VecA, 29, v29->as_VMReg()->next(3) ); 389 390 reg_def V30 ( SOC, SOC, Op_VecA, 30, v30->as_VMReg() ); 391 reg_def V30_H ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next() ); 392 reg_def V30_J ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(2) ); 393 reg_def V30_K ( SOC, SOC, Op_VecA, 30, v30->as_VMReg()->next(3) ); 394 395 reg_def V31 ( SOC, SOC, Op_VecA, 31, v31->as_VMReg() ); 396 reg_def V31_H ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next() ); 397 reg_def V31_J ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(2) ); 398 reg_def V31_K ( SOC, SOC, Op_VecA, 31, v31->as_VMReg()->next(3) ); 399 400 // ---------------------------- 401 // Special Registers 402 // ---------------------------- 403 404 // On riscv, the physical flag register is missing, so we use t1 instead, 405 // to bridge the RegFlag semantics in share/opto 406 407 reg_def RFLAGS (SOC, SOC, Op_RegFlags, 6, x6->as_VMReg() ); 408 409 // Specify priority of register selection within phases of register 410 // allocation. Highest priority is first. A useful heuristic is to 411 // give registers a low priority when they are required by machine 412 // instructions, like EAX and EDX on I486, and choose no-save registers 413 // before save-on-call, & save-on-call before save-on-entry. Registers 414 // which participate in fixed calling sequences should come last. 415 // Registers which are used as pairs must fall on an even boundary. 416 417 alloc_class chunk0( 418 // volatiles 419 R7, R7_H, 420 R28, R28_H, 421 R29, R29_H, 422 R30, R30_H, 423 R31, R31_H, 424 425 // arg registers 426 R10, R10_H, 427 R11, R11_H, 428 R12, R12_H, 429 R13, R13_H, 430 R14, R14_H, 431 R15, R15_H, 432 R16, R16_H, 433 R17, R17_H, 434 435 // non-volatiles 436 R9, R9_H, 437 R18, R18_H, 438 R19, R19_H, 439 R20, R20_H, 440 R21, R21_H, 441 R22, R22_H, 442 R24, R24_H, 443 R25, R25_H, 444 R26, R26_H, 445 446 // non-allocatable registers 447 R23, R23_H, // java thread 448 R27, R27_H, // heapbase 449 R4, R4_H, // thread 450 R8, R8_H, // fp 451 R0, R0_H, // zero 452 R1, R1_H, // ra 453 R2, R2_H, // sp 454 R3, R3_H, // gp 455 ); 456 457 alloc_class chunk1( 458 459 // no save 460 F0, F0_H, 461 F1, F1_H, 462 F2, F2_H, 463 F3, F3_H, 464 F4, F4_H, 465 F5, F5_H, 466 F6, F6_H, 467 F7, F7_H, 468 F28, F28_H, 469 F29, F29_H, 470 F30, F30_H, 471 F31, F31_H, 472 473 // arg registers 474 F10, F10_H, 475 F11, F11_H, 476 F12, F12_H, 477 F13, F13_H, 478 F14, F14_H, 479 F15, F15_H, 480 F16, F16_H, 481 F17, F17_H, 482 483 // non-volatiles 484 F8, F8_H, 485 F9, F9_H, 486 F18, F18_H, 487 F19, F19_H, 488 F20, F20_H, 489 F21, F21_H, 490 F22, F22_H, 491 F23, F23_H, 492 F24, F24_H, 493 F25, F25_H, 494 F26, F26_H, 495 F27, F27_H, 496 ); 497 498 alloc_class chunk2( 499 V0, V0_H, V0_J, V0_K, 500 V1, V1_H, V1_J, V1_K, 501 V2, V2_H, V2_J, V2_K, 502 V3, V3_H, V3_J, V3_K, 503 V4, V4_H, V4_J, V4_K, 504 V5, V5_H, V5_J, V5_K, 505 V6, V6_H, V6_J, V6_K, 506 V7, V7_H, V7_J, V7_K, 507 V8, V8_H, V8_J, V8_K, 508 V9, V9_H, V9_J, V9_K, 509 V10, V10_H, V10_J, V10_K, 510 V11, V11_H, V11_J, V11_K, 511 V12, V12_H, V12_J, V12_K, 512 V13, V13_H, V13_J, V13_K, 513 V14, V14_H, V14_J, V14_K, 514 V15, V15_H, V15_J, V15_K, 515 V16, V16_H, V16_J, V16_K, 516 V17, V17_H, V17_J, V17_K, 517 V18, V18_H, V18_J, V18_K, 518 V19, V19_H, V19_J, V19_K, 519 V20, V20_H, V20_J, V20_K, 520 V21, V21_H, V21_J, V21_K, 521 V22, V22_H, V22_J, V22_K, 522 V23, V23_H, V23_J, V23_K, 523 V24, V24_H, V24_J, V24_K, 524 V25, V25_H, V25_J, V25_K, 525 V26, V26_H, V26_J, V26_K, 526 V27, V27_H, V27_J, V27_K, 527 V28, V28_H, V28_J, V28_K, 528 V29, V29_H, V29_J, V29_K, 529 V30, V30_H, V30_J, V30_K, 530 V31, V31_H, V31_J, V31_K, 531 ); 532 533 alloc_class chunk3(RFLAGS); 534 535 //----------Architecture Description Register Classes-------------------------- 536 // Several register classes are automatically defined based upon information in 537 // this architecture description. 538 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 539 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 540 // 541 542 // Class for all 32 bit general purpose registers 543 reg_class all_reg32( 544 R0, 545 R1, 546 R2, 547 R3, 548 R4, 549 R7, 550 R8, 551 R9, 552 R10, 553 R11, 554 R12, 555 R13, 556 R14, 557 R15, 558 R16, 559 R17, 560 R18, 561 R19, 562 R20, 563 R21, 564 R22, 565 R23, 566 R24, 567 R25, 568 R26, 569 R27, 570 R28, 571 R29, 572 R30, 573 R31 574 ); 575 576 // Class for any 32 bit integer registers (excluding zr) 577 reg_class any_reg32 %{ 578 return _ANY_REG32_mask; 579 %} 580 581 // Singleton class for R10 int register 582 reg_class int_r10_reg(R10); 583 584 // Singleton class for R12 int register 585 reg_class int_r12_reg(R12); 586 587 // Singleton class for R13 int register 588 reg_class int_r13_reg(R13); 589 590 // Singleton class for R14 int register 591 reg_class int_r14_reg(R14); 592 593 // Class for all long integer registers 594 reg_class all_reg( 595 R0, R0_H, 596 R1, R1_H, 597 R2, R2_H, 598 R3, R3_H, 599 R4, R4_H, 600 R7, R7_H, 601 R8, R8_H, 602 R9, R9_H, 603 R10, R10_H, 604 R11, R11_H, 605 R12, R12_H, 606 R13, R13_H, 607 R14, R14_H, 608 R15, R15_H, 609 R16, R16_H, 610 R17, R17_H, 611 R18, R18_H, 612 R19, R19_H, 613 R20, R20_H, 614 R21, R21_H, 615 R22, R22_H, 616 R23, R23_H, 617 R24, R24_H, 618 R25, R25_H, 619 R26, R26_H, 620 R27, R27_H, 621 R28, R28_H, 622 R29, R29_H, 623 R30, R30_H, 624 R31, R31_H 625 ); 626 627 // Class for all long integer registers (excluding zr) 628 reg_class any_reg %{ 629 return _ANY_REG_mask; 630 %} 631 632 // Class for non-allocatable 32 bit registers 633 reg_class non_allocatable_reg32( 634 R0, // zr 635 R1, // ra 636 R2, // sp 637 R3, // gp 638 R4, // tp 639 R23 // java thread 640 ); 641 642 // Class for non-allocatable 64 bit registers 643 reg_class non_allocatable_reg( 644 R0, R0_H, // zr 645 R1, R1_H, // ra 646 R2, R2_H, // sp 647 R3, R3_H, // gp 648 R4, R4_H, // tp 649 R23, R23_H // java thread 650 ); 651 652 // Class for all non-special integer registers 653 reg_class no_special_reg32 %{ 654 return _NO_SPECIAL_REG32_mask; 655 %} 656 657 // Class for all non-special long integer registers 658 reg_class no_special_reg %{ 659 return _NO_SPECIAL_REG_mask; 660 %} 661 662 reg_class ptr_reg %{ 663 return _PTR_REG_mask; 664 %} 665 666 // Class for all non_special pointer registers 667 reg_class no_special_ptr_reg %{ 668 return _NO_SPECIAL_PTR_REG_mask; 669 %} 670 671 // Class for all non_special pointer registers (excluding fp) 672 reg_class no_special_no_fp_ptr_reg %{ 673 return _NO_SPECIAL_NO_FP_PTR_REG_mask; 674 %} 675 676 // Class for 64 bit register r10 677 reg_class r10_reg( 678 R10, R10_H 679 ); 680 681 // Class for 64 bit register r11 682 reg_class r11_reg( 683 R11, R11_H 684 ); 685 686 // Class for 64 bit register r12 687 reg_class r12_reg( 688 R12, R12_H 689 ); 690 691 // Class for 64 bit register r13 692 reg_class r13_reg( 693 R13, R13_H 694 ); 695 696 // Class for 64 bit register r14 697 reg_class r14_reg( 698 R14, R14_H 699 ); 700 701 // Class for 64 bit register r15 702 reg_class r15_reg( 703 R15, R15_H 704 ); 705 706 // Class for 64 bit register r16 707 reg_class r16_reg( 708 R16, R16_H 709 ); 710 711 // Class for method register 712 reg_class method_reg( 713 R31, R31_H 714 ); 715 716 // Class for java thread register 717 reg_class java_thread_reg( 718 R23, R23_H 719 ); 720 721 reg_class r28_reg( 722 R28, R28_H 723 ); 724 725 reg_class r29_reg( 726 R29, R29_H 727 ); 728 729 reg_class r30_reg( 730 R30, R30_H 731 ); 732 733 reg_class r31_reg( 734 R31, R31_H 735 ); 736 737 // Class for zero registesr 738 reg_class zr_reg( 739 R0, R0_H 740 ); 741 742 // Class for thread register 743 reg_class thread_reg( 744 R4, R4_H 745 ); 746 747 // Class for frame pointer register 748 reg_class fp_reg( 749 R8, R8_H 750 ); 751 752 // Class for link register 753 reg_class ra_reg( 754 R1, R1_H 755 ); 756 757 // Class for long sp register 758 reg_class sp_reg( 759 R2, R2_H 760 ); 761 762 // Class for all float registers 763 reg_class float_reg( 764 F0, 765 F1, 766 F2, 767 F3, 768 F4, 769 F5, 770 F6, 771 F7, 772 F8, 773 F9, 774 F10, 775 F11, 776 F12, 777 F13, 778 F14, 779 F15, 780 F16, 781 F17, 782 F18, 783 F19, 784 F20, 785 F21, 786 F22, 787 F23, 788 F24, 789 F25, 790 F26, 791 F27, 792 F28, 793 F29, 794 F30, 795 F31 796 ); 797 798 // Double precision float registers have virtual `high halves' that 799 // are needed by the allocator. 800 // Class for all double registers 801 reg_class double_reg( 802 F0, F0_H, 803 F1, F1_H, 804 F2, F2_H, 805 F3, F3_H, 806 F4, F4_H, 807 F5, F5_H, 808 F6, F6_H, 809 F7, F7_H, 810 F8, F8_H, 811 F9, F9_H, 812 F10, F10_H, 813 F11, F11_H, 814 F12, F12_H, 815 F13, F13_H, 816 F14, F14_H, 817 F15, F15_H, 818 F16, F16_H, 819 F17, F17_H, 820 F18, F18_H, 821 F19, F19_H, 822 F20, F20_H, 823 F21, F21_H, 824 F22, F22_H, 825 F23, F23_H, 826 F24, F24_H, 827 F25, F25_H, 828 F26, F26_H, 829 F27, F27_H, 830 F28, F28_H, 831 F29, F29_H, 832 F30, F30_H, 833 F31, F31_H 834 ); 835 836 // Class for RVV vector registers 837 // Note: v0, v30 and v31 are used as mask registers. 838 reg_class vectora_reg( 839 V1, V1_H, V1_J, V1_K, 840 V2, V2_H, V2_J, V2_K, 841 V3, V3_H, V3_J, V3_K, 842 V4, V4_H, V4_J, V4_K, 843 V5, V5_H, V5_J, V5_K, 844 V6, V6_H, V6_J, V6_K, 845 V7, V7_H, V7_J, V7_K, 846 V8, V8_H, V8_J, V8_K, 847 V9, V9_H, V9_J, V9_K, 848 V10, V10_H, V10_J, V10_K, 849 V11, V11_H, V11_J, V11_K, 850 V12, V12_H, V12_J, V12_K, 851 V13, V13_H, V13_J, V13_K, 852 V14, V14_H, V14_J, V14_K, 853 V15, V15_H, V15_J, V15_K, 854 V16, V16_H, V16_J, V16_K, 855 V17, V17_H, V17_J, V17_K, 856 V18, V18_H, V18_J, V18_K, 857 V19, V19_H, V19_J, V19_K, 858 V20, V20_H, V20_J, V20_K, 859 V21, V21_H, V21_J, V21_K, 860 V22, V22_H, V22_J, V22_K, 861 V23, V23_H, V23_J, V23_K, 862 V24, V24_H, V24_J, V24_K, 863 V25, V25_H, V25_J, V25_K, 864 V26, V26_H, V26_J, V26_K, 865 V27, V27_H, V27_J, V27_K, 866 V28, V28_H, V28_J, V28_K, 867 V29, V29_H, V29_J, V29_K 868 ); 869 870 // Class for 64 bit register f0 871 reg_class f0_reg( 872 F0, F0_H 873 ); 874 875 // Class for 64 bit register f1 876 reg_class f1_reg( 877 F1, F1_H 878 ); 879 880 // Class for 64 bit register f2 881 reg_class f2_reg( 882 F2, F2_H 883 ); 884 885 // Class for 64 bit register f3 886 reg_class f3_reg( 887 F3, F3_H 888 ); 889 890 // class for vector register v1 891 reg_class v1_reg( 892 V1, V1_H, V1_J, V1_K 893 ); 894 895 // class for vector register v2 896 reg_class v2_reg( 897 V2, V2_H, V2_J, V2_K 898 ); 899 900 // class for vector register v3 901 reg_class v3_reg( 902 V3, V3_H, V3_J, V3_K 903 ); 904 905 // class for vector register v4 906 reg_class v4_reg( 907 V4, V4_H, V4_J, V4_K 908 ); 909 910 // class for vector register v5 911 reg_class v5_reg( 912 V5, V5_H, V5_J, V5_K 913 ); 914 915 // class for vector register v6 916 reg_class v6_reg( 917 V6, V6_H, V6_J, V6_K 918 ); 919 920 // class for vector register v7 921 reg_class v7_reg( 922 V7, V7_H, V7_J, V7_K 923 ); 924 925 // class for vector register v8 926 reg_class v8_reg( 927 V8, V8_H, V8_J, V8_K 928 ); 929 930 // class for vector register v9 931 reg_class v9_reg( 932 V9, V9_H, V9_J, V9_K 933 ); 934 935 // class for vector register v10 936 reg_class v10_reg( 937 V10, V10_H, V10_J, V10_K 938 ); 939 940 // class for vector register v11 941 reg_class v11_reg( 942 V11, V11_H, V11_J, V11_K 943 ); 944 945 // class for 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 SHENANDOAHGC_ONLY(!BarrierSet::barrier_set()->is_a(BarrierSet::ShenandoahBarrierSet) &&) 2879 (CardTable::CardValue*)n->get_ptr() == 2880 ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 2881 match(ConP); 2882 2883 op_cost(0); 2884 format %{ %} 2885 interface(CONST_INTER); 2886 %} 2887 2888 // Int Immediate: low 16-bit mask 2889 operand immI_16bits() 2890 %{ 2891 predicate(n->get_int() == 0xFFFF); 2892 match(ConI); 2893 op_cost(0); 2894 format %{ %} 2895 interface(CONST_INTER); 2896 %} 2897 2898 operand immIpowerOf2() %{ 2899 predicate(is_power_of_2((juint)(n->get_int()))); 2900 match(ConI); 2901 op_cost(0); 2902 format %{ %} 2903 interface(CONST_INTER); 2904 %} 2905 2906 // Long Immediate: low 32-bit mask 2907 operand immL_32bits() 2908 %{ 2909 predicate(n->get_long() == 0xFFFFFFFFL); 2910 match(ConL); 2911 op_cost(0); 2912 format %{ %} 2913 interface(CONST_INTER); 2914 %} 2915 2916 // 64 bit unit decrement 2917 operand immL_M1() 2918 %{ 2919 predicate(n->get_long() == -1); 2920 match(ConL); 2921 2922 op_cost(0); 2923 format %{ %} 2924 interface(CONST_INTER); 2925 %} 2926 2927 2928 // 32 bit offset of pc in thread anchor 2929 2930 operand immL_pc_off() 2931 %{ 2932 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 2933 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 2934 match(ConL); 2935 2936 op_cost(0); 2937 format %{ %} 2938 interface(CONST_INTER); 2939 %} 2940 2941 // 64 bit integer valid for add immediate 2942 operand immLAdd() 2943 %{ 2944 predicate(Assembler::is_simm12(n->get_long())); 2945 match(ConL); 2946 op_cost(0); 2947 format %{ %} 2948 interface(CONST_INTER); 2949 %} 2950 2951 // 64 bit integer valid for sub immediate 2952 operand immLSub() 2953 %{ 2954 predicate(Assembler::is_simm12(-(n->get_long()))); 2955 match(ConL); 2956 op_cost(0); 2957 format %{ %} 2958 interface(CONST_INTER); 2959 %} 2960 2961 // Narrow pointer operands 2962 // Narrow Pointer Immediate 2963 operand immN() 2964 %{ 2965 match(ConN); 2966 2967 op_cost(0); 2968 format %{ %} 2969 interface(CONST_INTER); 2970 %} 2971 2972 // Narrow NULL Pointer Immediate 2973 operand immN0() 2974 %{ 2975 predicate(n->get_narrowcon() == 0); 2976 match(ConN); 2977 2978 op_cost(0); 2979 format %{ %} 2980 interface(CONST_INTER); 2981 %} 2982 2983 operand immNKlass() 2984 %{ 2985 match(ConNKlass); 2986 2987 op_cost(0); 2988 format %{ %} 2989 interface(CONST_INTER); 2990 %} 2991 2992 // Float and Double operands 2993 // Double Immediate 2994 operand immD() 2995 %{ 2996 match(ConD); 2997 op_cost(0); 2998 format %{ %} 2999 interface(CONST_INTER); 3000 %} 3001 3002 // Double Immediate: +0.0d 3003 operand immD0() 3004 %{ 3005 predicate(jlong_cast(n->getd()) == 0); 3006 match(ConD); 3007 3008 op_cost(0); 3009 format %{ %} 3010 interface(CONST_INTER); 3011 %} 3012 3013 // Float Immediate 3014 operand immF() 3015 %{ 3016 match(ConF); 3017 op_cost(0); 3018 format %{ %} 3019 interface(CONST_INTER); 3020 %} 3021 3022 // Float Immediate: +0.0f. 3023 operand immF0() 3024 %{ 3025 predicate(jint_cast(n->getf()) == 0); 3026 match(ConF); 3027 3028 op_cost(0); 3029 format %{ %} 3030 interface(CONST_INTER); 3031 %} 3032 3033 operand immIOffset() 3034 %{ 3035 predicate(Assembler::is_simm12(n->get_int())); 3036 match(ConI); 3037 op_cost(0); 3038 format %{ %} 3039 interface(CONST_INTER); 3040 %} 3041 3042 operand immLOffset() 3043 %{ 3044 predicate(Assembler::is_simm12(n->get_long())); 3045 match(ConL); 3046 op_cost(0); 3047 format %{ %} 3048 interface(CONST_INTER); 3049 %} 3050 3051 // Scale values 3052 operand immIScale() 3053 %{ 3054 predicate(1 <= n->get_int() && (n->get_int() <= 3)); 3055 match(ConI); 3056 3057 op_cost(0); 3058 format %{ %} 3059 interface(CONST_INTER); 3060 %} 3061 3062 // Integer 32 bit Register Operands 3063 operand iRegI() 3064 %{ 3065 constraint(ALLOC_IN_RC(any_reg32)); 3066 match(RegI); 3067 match(iRegINoSp); 3068 op_cost(0); 3069 format %{ %} 3070 interface(REG_INTER); 3071 %} 3072 3073 // Integer 32 bit Register not Special 3074 operand iRegINoSp() 3075 %{ 3076 constraint(ALLOC_IN_RC(no_special_reg32)); 3077 match(RegI); 3078 op_cost(0); 3079 format %{ %} 3080 interface(REG_INTER); 3081 %} 3082 3083 // Register R10 only 3084 operand iRegI_R10() 3085 %{ 3086 constraint(ALLOC_IN_RC(int_r10_reg)); 3087 match(RegI); 3088 match(iRegINoSp); 3089 op_cost(0); 3090 format %{ %} 3091 interface(REG_INTER); 3092 %} 3093 3094 // Register R12 only 3095 operand iRegI_R12() 3096 %{ 3097 constraint(ALLOC_IN_RC(int_r12_reg)); 3098 match(RegI); 3099 match(iRegINoSp); 3100 op_cost(0); 3101 format %{ %} 3102 interface(REG_INTER); 3103 %} 3104 3105 // Register R13 only 3106 operand iRegI_R13() 3107 %{ 3108 constraint(ALLOC_IN_RC(int_r13_reg)); 3109 match(RegI); 3110 match(iRegINoSp); 3111 op_cost(0); 3112 format %{ %} 3113 interface(REG_INTER); 3114 %} 3115 3116 // Register R14 only 3117 operand iRegI_R14() 3118 %{ 3119 constraint(ALLOC_IN_RC(int_r14_reg)); 3120 match(RegI); 3121 match(iRegINoSp); 3122 op_cost(0); 3123 format %{ %} 3124 interface(REG_INTER); 3125 %} 3126 3127 // Integer 64 bit Register Operands 3128 operand iRegL() 3129 %{ 3130 constraint(ALLOC_IN_RC(any_reg)); 3131 match(RegL); 3132 match(iRegLNoSp); 3133 op_cost(0); 3134 format %{ %} 3135 interface(REG_INTER); 3136 %} 3137 3138 // Integer 64 bit Register not Special 3139 operand iRegLNoSp() 3140 %{ 3141 constraint(ALLOC_IN_RC(no_special_reg)); 3142 match(RegL); 3143 match(iRegL_R10); 3144 format %{ %} 3145 interface(REG_INTER); 3146 %} 3147 3148 // Long 64 bit Register R28 only 3149 operand iRegL_R28() 3150 %{ 3151 constraint(ALLOC_IN_RC(r28_reg)); 3152 match(RegL); 3153 match(iRegLNoSp); 3154 op_cost(0); 3155 format %{ %} 3156 interface(REG_INTER); 3157 %} 3158 3159 // Long 64 bit Register R29 only 3160 operand iRegL_R29() 3161 %{ 3162 constraint(ALLOC_IN_RC(r29_reg)); 3163 match(RegL); 3164 match(iRegLNoSp); 3165 op_cost(0); 3166 format %{ %} 3167 interface(REG_INTER); 3168 %} 3169 3170 // Long 64 bit Register R30 only 3171 operand iRegL_R30() 3172 %{ 3173 constraint(ALLOC_IN_RC(r30_reg)); 3174 match(RegL); 3175 match(iRegLNoSp); 3176 op_cost(0); 3177 format %{ %} 3178 interface(REG_INTER); 3179 %} 3180 3181 // Pointer Register Operands 3182 // Pointer Register 3183 operand iRegP() 3184 %{ 3185 constraint(ALLOC_IN_RC(ptr_reg)); 3186 match(RegP); 3187 match(iRegPNoSp); 3188 match(iRegP_R10); 3189 match(iRegP_R15); 3190 match(javaThread_RegP); 3191 op_cost(0); 3192 format %{ %} 3193 interface(REG_INTER); 3194 %} 3195 3196 // Pointer 64 bit Register not Special 3197 operand iRegPNoSp() 3198 %{ 3199 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 3200 match(RegP); 3201 op_cost(0); 3202 format %{ %} 3203 interface(REG_INTER); 3204 %} 3205 3206 // This operand is not allowed to use fp even if 3207 // fp is not used to hold the frame pointer. 3208 operand iRegPNoSpNoFp() 3209 %{ 3210 constraint(ALLOC_IN_RC(no_special_no_fp_ptr_reg)); 3211 match(RegP); 3212 match(iRegPNoSp); 3213 op_cost(0); 3214 format %{ %} 3215 interface(REG_INTER); 3216 %} 3217 3218 operand iRegP_R10() 3219 %{ 3220 constraint(ALLOC_IN_RC(r10_reg)); 3221 match(RegP); 3222 // match(iRegP); 3223 match(iRegPNoSp); 3224 op_cost(0); 3225 format %{ %} 3226 interface(REG_INTER); 3227 %} 3228 3229 // Pointer 64 bit Register R11 only 3230 operand iRegP_R11() 3231 %{ 3232 constraint(ALLOC_IN_RC(r11_reg)); 3233 match(RegP); 3234 match(iRegPNoSp); 3235 op_cost(0); 3236 format %{ %} 3237 interface(REG_INTER); 3238 %} 3239 3240 operand iRegP_R12() 3241 %{ 3242 constraint(ALLOC_IN_RC(r12_reg)); 3243 match(RegP); 3244 // match(iRegP); 3245 match(iRegPNoSp); 3246 op_cost(0); 3247 format %{ %} 3248 interface(REG_INTER); 3249 %} 3250 3251 // Pointer 64 bit Register R13 only 3252 operand iRegP_R13() 3253 %{ 3254 constraint(ALLOC_IN_RC(r13_reg)); 3255 match(RegP); 3256 match(iRegPNoSp); 3257 op_cost(0); 3258 format %{ %} 3259 interface(REG_INTER); 3260 %} 3261 3262 operand iRegP_R14() 3263 %{ 3264 constraint(ALLOC_IN_RC(r14_reg)); 3265 match(RegP); 3266 // match(iRegP); 3267 match(iRegPNoSp); 3268 op_cost(0); 3269 format %{ %} 3270 interface(REG_INTER); 3271 %} 3272 3273 operand iRegP_R15() 3274 %{ 3275 constraint(ALLOC_IN_RC(r15_reg)); 3276 match(RegP); 3277 // match(iRegP); 3278 match(iRegPNoSp); 3279 op_cost(0); 3280 format %{ %} 3281 interface(REG_INTER); 3282 %} 3283 3284 operand iRegP_R16() 3285 %{ 3286 constraint(ALLOC_IN_RC(r16_reg)); 3287 match(RegP); 3288 // match(iRegP); 3289 match(iRegPNoSp); 3290 op_cost(0); 3291 format %{ %} 3292 interface(REG_INTER); 3293 %} 3294 3295 // Pointer 64 bit Register R28 only 3296 operand iRegP_R28() 3297 %{ 3298 constraint(ALLOC_IN_RC(r28_reg)); 3299 match(RegP); 3300 match(iRegPNoSp); 3301 op_cost(0); 3302 format %{ %} 3303 interface(REG_INTER); 3304 %} 3305 3306 // Pointer 64 bit Register R30 only 3307 operand iRegP_R30() 3308 %{ 3309 constraint(ALLOC_IN_RC(r30_reg)); 3310 match(RegP); 3311 match(iRegPNoSp); 3312 op_cost(0); 3313 format %{ %} 3314 interface(REG_INTER); 3315 %} 3316 3317 // Pointer 64 bit Register R31 only 3318 operand iRegP_R31() 3319 %{ 3320 constraint(ALLOC_IN_RC(r31_reg)); 3321 match(RegP); 3322 match(iRegPNoSp); 3323 op_cost(0); 3324 format %{ %} 3325 interface(REG_INTER); 3326 %} 3327 3328 // Pointer Register Operands 3329 // Narrow Pointer Register 3330 operand iRegN() 3331 %{ 3332 constraint(ALLOC_IN_RC(any_reg32)); 3333 match(RegN); 3334 match(iRegNNoSp); 3335 op_cost(0); 3336 format %{ %} 3337 interface(REG_INTER); 3338 %} 3339 3340 // Integer 64 bit Register not Special 3341 operand iRegNNoSp() 3342 %{ 3343 constraint(ALLOC_IN_RC(no_special_reg32)); 3344 match(RegN); 3345 op_cost(0); 3346 format %{ %} 3347 interface(REG_INTER); 3348 %} 3349 3350 // Long 64 bit Register R10 only 3351 operand iRegL_R10() 3352 %{ 3353 constraint(ALLOC_IN_RC(r10_reg)); 3354 match(RegL); 3355 match(iRegLNoSp); 3356 op_cost(0); 3357 format %{ %} 3358 interface(REG_INTER); 3359 %} 3360 3361 // Float Register 3362 // Float register operands 3363 operand fRegF() 3364 %{ 3365 constraint(ALLOC_IN_RC(float_reg)); 3366 match(RegF); 3367 3368 op_cost(0); 3369 format %{ %} 3370 interface(REG_INTER); 3371 %} 3372 3373 // Double Register 3374 // Double register operands 3375 operand fRegD() 3376 %{ 3377 constraint(ALLOC_IN_RC(double_reg)); 3378 match(RegD); 3379 3380 op_cost(0); 3381 format %{ %} 3382 interface(REG_INTER); 3383 %} 3384 3385 // Generic vector class. This will be used for 3386 // all vector operands. 3387 operand vReg() 3388 %{ 3389 constraint(ALLOC_IN_RC(vectora_reg)); 3390 match(VecA); 3391 op_cost(0); 3392 format %{ %} 3393 interface(REG_INTER); 3394 %} 3395 3396 operand vReg_V1() 3397 %{ 3398 constraint(ALLOC_IN_RC(v1_reg)); 3399 match(VecA); 3400 match(vReg); 3401 op_cost(0); 3402 format %{ %} 3403 interface(REG_INTER); 3404 %} 3405 3406 operand vReg_V2() 3407 %{ 3408 constraint(ALLOC_IN_RC(v2_reg)); 3409 match(VecA); 3410 match(vReg); 3411 op_cost(0); 3412 format %{ %} 3413 interface(REG_INTER); 3414 %} 3415 3416 operand vReg_V3() 3417 %{ 3418 constraint(ALLOC_IN_RC(v3_reg)); 3419 match(VecA); 3420 match(vReg); 3421 op_cost(0); 3422 format %{ %} 3423 interface(REG_INTER); 3424 %} 3425 3426 operand vReg_V4() 3427 %{ 3428 constraint(ALLOC_IN_RC(v4_reg)); 3429 match(VecA); 3430 match(vReg); 3431 op_cost(0); 3432 format %{ %} 3433 interface(REG_INTER); 3434 %} 3435 3436 operand vReg_V5() 3437 %{ 3438 constraint(ALLOC_IN_RC(v5_reg)); 3439 match(VecA); 3440 match(vReg); 3441 op_cost(0); 3442 format %{ %} 3443 interface(REG_INTER); 3444 %} 3445 3446 operand vReg_V6() 3447 %{ 3448 constraint(ALLOC_IN_RC(v6_reg)); 3449 match(VecA); 3450 match(vReg); 3451 op_cost(0); 3452 format %{ %} 3453 interface(REG_INTER); 3454 %} 3455 3456 operand vReg_V7() 3457 %{ 3458 constraint(ALLOC_IN_RC(v7_reg)); 3459 match(VecA); 3460 match(vReg); 3461 op_cost(0); 3462 format %{ %} 3463 interface(REG_INTER); 3464 %} 3465 3466 operand vReg_V8() 3467 %{ 3468 constraint(ALLOC_IN_RC(v8_reg)); 3469 match(VecA); 3470 match(vReg); 3471 op_cost(0); 3472 format %{ %} 3473 interface(REG_INTER); 3474 %} 3475 3476 operand vReg_V9() 3477 %{ 3478 constraint(ALLOC_IN_RC(v9_reg)); 3479 match(VecA); 3480 match(vReg); 3481 op_cost(0); 3482 format %{ %} 3483 interface(REG_INTER); 3484 %} 3485 3486 operand vReg_V10() 3487 %{ 3488 constraint(ALLOC_IN_RC(v10_reg)); 3489 match(VecA); 3490 match(vReg); 3491 op_cost(0); 3492 format %{ %} 3493 interface(REG_INTER); 3494 %} 3495 3496 operand vReg_V11() 3497 %{ 3498 constraint(ALLOC_IN_RC(v11_reg)); 3499 match(VecA); 3500 match(vReg); 3501 op_cost(0); 3502 format %{ %} 3503 interface(REG_INTER); 3504 %} 3505 3506 operand vRegMask() 3507 %{ 3508 constraint(ALLOC_IN_RC(vmask_reg)); 3509 match(RegVectMask); 3510 match(vRegMask_V0); 3511 op_cost(0); 3512 format %{ %} 3513 interface(REG_INTER); 3514 %} 3515 3516 // The mask value used to control execution of a masked 3517 // vector instruction is always supplied by vector register v0. 3518 operand vRegMask_V0() 3519 %{ 3520 constraint(ALLOC_IN_RC(vmask_reg_v0)); 3521 match(RegVectMask); 3522 match(vRegMask); 3523 op_cost(0); 3524 format %{ %} 3525 interface(REG_INTER); 3526 %} 3527 3528 // Java Thread Register 3529 operand javaThread_RegP(iRegP reg) 3530 %{ 3531 constraint(ALLOC_IN_RC(java_thread_reg)); // java_thread_reg 3532 match(reg); 3533 op_cost(0); 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 //----------Memory Operands---------------------------------------------------- 3539 // RISCV has only base_plus_offset and literal address mode, so no need to use 3540 // index and scale. Here set index as 0xffffffff and scale as 0x0. 3541 operand indirect(iRegP reg) 3542 %{ 3543 constraint(ALLOC_IN_RC(ptr_reg)); 3544 match(reg); 3545 op_cost(0); 3546 format %{ "[$reg]" %} 3547 interface(MEMORY_INTER) %{ 3548 base($reg); 3549 index(0xffffffff); 3550 scale(0x0); 3551 disp(0x0); 3552 %} 3553 %} 3554 3555 operand indOffI(iRegP reg, immIOffset off) 3556 %{ 3557 constraint(ALLOC_IN_RC(ptr_reg)); 3558 match(AddP reg off); 3559 op_cost(0); 3560 format %{ "[$reg, $off]" %} 3561 interface(MEMORY_INTER) %{ 3562 base($reg); 3563 index(0xffffffff); 3564 scale(0x0); 3565 disp($off); 3566 %} 3567 %} 3568 3569 operand indOffL(iRegP reg, immLOffset off) 3570 %{ 3571 constraint(ALLOC_IN_RC(ptr_reg)); 3572 match(AddP reg off); 3573 op_cost(0); 3574 format %{ "[$reg, $off]" %} 3575 interface(MEMORY_INTER) %{ 3576 base($reg); 3577 index(0xffffffff); 3578 scale(0x0); 3579 disp($off); 3580 %} 3581 %} 3582 3583 operand indirectN(iRegN reg) 3584 %{ 3585 predicate(CompressedOops::shift() == 0); 3586 constraint(ALLOC_IN_RC(ptr_reg)); 3587 match(DecodeN reg); 3588 op_cost(0); 3589 format %{ "[$reg]\t# narrow" %} 3590 interface(MEMORY_INTER) %{ 3591 base($reg); 3592 index(0xffffffff); 3593 scale(0x0); 3594 disp(0x0); 3595 %} 3596 %} 3597 3598 operand indOffIN(iRegN reg, immIOffset off) 3599 %{ 3600 predicate(CompressedOops::shift() == 0); 3601 constraint(ALLOC_IN_RC(ptr_reg)); 3602 match(AddP (DecodeN reg) off); 3603 op_cost(0); 3604 format %{ "[$reg, $off]\t# narrow" %} 3605 interface(MEMORY_INTER) %{ 3606 base($reg); 3607 index(0xffffffff); 3608 scale(0x0); 3609 disp($off); 3610 %} 3611 %} 3612 3613 operand indOffLN(iRegN reg, immLOffset off) 3614 %{ 3615 predicate(CompressedOops::shift() == 0); 3616 constraint(ALLOC_IN_RC(ptr_reg)); 3617 match(AddP (DecodeN reg) off); 3618 op_cost(0); 3619 format %{ "[$reg, $off]\t# narrow" %} 3620 interface(MEMORY_INTER) %{ 3621 base($reg); 3622 index(0xffffffff); 3623 scale(0x0); 3624 disp($off); 3625 %} 3626 %} 3627 3628 // RISCV opto stubs need to write to the pc slot in the thread anchor 3629 operand thread_anchor_pc(javaThread_RegP reg, immL_pc_off off) 3630 %{ 3631 constraint(ALLOC_IN_RC(ptr_reg)); 3632 match(AddP reg off); 3633 op_cost(0); 3634 format %{ "[$reg, $off]" %} 3635 interface(MEMORY_INTER) %{ 3636 base($reg); 3637 index(0xffffffff); 3638 scale(0x0); 3639 disp($off); 3640 %} 3641 %} 3642 3643 3644 //----------Special Memory Operands-------------------------------------------- 3645 // Stack Slot Operand - This operand is used for loading and storing temporary 3646 // values on the stack where a match requires a value to 3647 // flow through memory. 3648 operand stackSlotI(sRegI reg) 3649 %{ 3650 constraint(ALLOC_IN_RC(stack_slots)); 3651 // No match rule because this operand is only generated in matching 3652 // match(RegI); 3653 format %{ "[$reg]" %} 3654 interface(MEMORY_INTER) %{ 3655 base(0x02); // RSP 3656 index(0xffffffff); // No Index 3657 scale(0x0); // No Scale 3658 disp($reg); // Stack Offset 3659 %} 3660 %} 3661 3662 operand stackSlotF(sRegF reg) 3663 %{ 3664 constraint(ALLOC_IN_RC(stack_slots)); 3665 // No match rule because this operand is only generated in matching 3666 // match(RegF); 3667 format %{ "[$reg]" %} 3668 interface(MEMORY_INTER) %{ 3669 base(0x02); // RSP 3670 index(0xffffffff); // No Index 3671 scale(0x0); // No Scale 3672 disp($reg); // Stack Offset 3673 %} 3674 %} 3675 3676 operand stackSlotD(sRegD reg) 3677 %{ 3678 constraint(ALLOC_IN_RC(stack_slots)); 3679 // No match rule because this operand is only generated in matching 3680 // match(RegD); 3681 format %{ "[$reg]" %} 3682 interface(MEMORY_INTER) %{ 3683 base(0x02); // RSP 3684 index(0xffffffff); // No Index 3685 scale(0x0); // No Scale 3686 disp($reg); // Stack Offset 3687 %} 3688 %} 3689 3690 operand stackSlotL(sRegL reg) 3691 %{ 3692 constraint(ALLOC_IN_RC(stack_slots)); 3693 // No match rule because this operand is only generated in matching 3694 // match(RegL); 3695 format %{ "[$reg]" %} 3696 interface(MEMORY_INTER) %{ 3697 base(0x02); // RSP 3698 index(0xffffffff); // No Index 3699 scale(0x0); // No Scale 3700 disp($reg); // Stack Offset 3701 %} 3702 %} 3703 3704 // Special operand allowing long args to int ops to be truncated for free 3705 3706 operand iRegL2I(iRegL reg) %{ 3707 3708 op_cost(0); 3709 3710 match(ConvL2I reg); 3711 3712 format %{ "l2i($reg)" %} 3713 3714 interface(REG_INTER) 3715 %} 3716 3717 3718 // Comparison Operands 3719 // NOTE: Label is a predefined operand which should not be redefined in 3720 // the AD file. It is generically handled within the ADLC. 3721 3722 //----------Conditional Branch Operands---------------------------------------- 3723 // Comparison Op - This is the operation of the comparison, and is limited to 3724 // the following set of codes: 3725 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3726 // 3727 // Other attributes of the comparison, such as unsignedness, are specified 3728 // by the comparison instruction that sets a condition code flags register. 3729 // That result is represented by a flags operand whose subtype is appropriate 3730 // to the unsignedness (etc.) of the comparison. 3731 // 3732 // Later, the instruction which matches both the Comparison Op (a Bool) and 3733 // the flags (produced by the Cmp) specifies the coding of the comparison op 3734 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3735 3736 3737 // used for signed integral comparisons and fp comparisons 3738 operand cmpOp() 3739 %{ 3740 match(Bool); 3741 3742 format %{ "" %} 3743 3744 // the values in interface derives from struct BoolTest::mask 3745 interface(COND_INTER) %{ 3746 equal(0x0, "eq"); 3747 greater(0x1, "gt"); 3748 overflow(0x2, "overflow"); 3749 less(0x3, "lt"); 3750 not_equal(0x4, "ne"); 3751 less_equal(0x5, "le"); 3752 no_overflow(0x6, "no_overflow"); 3753 greater_equal(0x7, "ge"); 3754 %} 3755 %} 3756 3757 // used for unsigned integral comparisons 3758 operand cmpOpU() 3759 %{ 3760 match(Bool); 3761 3762 format %{ "" %} 3763 // the values in interface derives from struct BoolTest::mask 3764 interface(COND_INTER) %{ 3765 equal(0x0, "eq"); 3766 greater(0x1, "gtu"); 3767 overflow(0x2, "overflow"); 3768 less(0x3, "ltu"); 3769 not_equal(0x4, "ne"); 3770 less_equal(0x5, "leu"); 3771 no_overflow(0x6, "no_overflow"); 3772 greater_equal(0x7, "geu"); 3773 %} 3774 %} 3775 3776 // used for certain integral comparisons which can be 3777 // converted to bxx instructions 3778 operand cmpOpEqNe() 3779 %{ 3780 match(Bool); 3781 op_cost(0); 3782 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3783 n->as_Bool()->_test._test == BoolTest::eq); 3784 3785 format %{ "" %} 3786 interface(COND_INTER) %{ 3787 equal(0x0, "eq"); 3788 greater(0x1, "gt"); 3789 overflow(0x2, "overflow"); 3790 less(0x3, "lt"); 3791 not_equal(0x4, "ne"); 3792 less_equal(0x5, "le"); 3793 no_overflow(0x6, "no_overflow"); 3794 greater_equal(0x7, "ge"); 3795 %} 3796 %} 3797 3798 operand cmpOpULtGe() 3799 %{ 3800 match(Bool); 3801 op_cost(0); 3802 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3803 n->as_Bool()->_test._test == BoolTest::ge); 3804 3805 format %{ "" %} 3806 interface(COND_INTER) %{ 3807 equal(0x0, "eq"); 3808 greater(0x1, "gtu"); 3809 overflow(0x2, "overflow"); 3810 less(0x3, "ltu"); 3811 not_equal(0x4, "ne"); 3812 less_equal(0x5, "leu"); 3813 no_overflow(0x6, "no_overflow"); 3814 greater_equal(0x7, "geu"); 3815 %} 3816 %} 3817 3818 operand cmpOpUEqNeLeGt() 3819 %{ 3820 match(Bool); 3821 op_cost(0); 3822 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3823 n->as_Bool()->_test._test == BoolTest::eq || 3824 n->as_Bool()->_test._test == BoolTest::le || 3825 n->as_Bool()->_test._test == BoolTest::gt); 3826 3827 format %{ "" %} 3828 interface(COND_INTER) %{ 3829 equal(0x0, "eq"); 3830 greater(0x1, "gtu"); 3831 overflow(0x2, "overflow"); 3832 less(0x3, "ltu"); 3833 not_equal(0x4, "ne"); 3834 less_equal(0x5, "leu"); 3835 no_overflow(0x6, "no_overflow"); 3836 greater_equal(0x7, "geu"); 3837 %} 3838 %} 3839 3840 3841 // Flags register, used as output of compare logic 3842 operand rFlagsReg() 3843 %{ 3844 constraint(ALLOC_IN_RC(reg_flags)); 3845 match(RegFlags); 3846 3847 op_cost(0); 3848 format %{ "RFLAGS" %} 3849 interface(REG_INTER); 3850 %} 3851 3852 // Special Registers 3853 3854 // Method Register 3855 operand inline_cache_RegP(iRegP reg) 3856 %{ 3857 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 3858 match(reg); 3859 match(iRegPNoSp); 3860 op_cost(0); 3861 format %{ %} 3862 interface(REG_INTER); 3863 %} 3864 3865 //----------OPERAND CLASSES---------------------------------------------------- 3866 // Operand Classes are groups of operands that are used as to simplify 3867 // instruction definitions by not requiring the AD writer to specify 3868 // separate instructions for every form of operand when the 3869 // instruction accepts multiple operand types with the same basic 3870 // encoding and format. The classic case of this is memory operands. 3871 3872 // memory is used to define read/write location for load/store 3873 // instruction defs. we can turn a memory op into an Address 3874 3875 opclass memory(indirect, indOffI, indOffL, indirectN, indOffIN, indOffLN); 3876 3877 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 3878 // operations. it allows the src to be either an iRegI or a (ConvL2I 3879 // iRegL). in the latter case the l2i normally planted for a ConvL2I 3880 // can be elided because the 32-bit instruction will just employ the 3881 // lower 32 bits anyway. 3882 // 3883 // n.b. this does not elide all L2I conversions. if the truncated 3884 // value is consumed by more than one operation then the ConvL2I 3885 // cannot be bundled into the consuming nodes so an l2i gets planted 3886 // (actually an addiw $dst, $src, 0) and the downstream instructions 3887 // consume the result of the L2I as an iRegI input. That's a shame since 3888 // the addiw is actually redundant but its not too costly. 3889 3890 opclass iRegIorL2I(iRegI, iRegL2I); 3891 opclass iRegIorL(iRegI, iRegL); 3892 opclass iRegNorP(iRegN, iRegP); 3893 opclass iRegILNP(iRegI, iRegL, iRegN, iRegP); 3894 opclass iRegILNPNoSp(iRegINoSp, iRegLNoSp, iRegNNoSp, iRegPNoSp); 3895 opclass immIorL(immI, immL); 3896 3897 //----------PIPELINE----------------------------------------------------------- 3898 // Rules which define the behavior of the target architectures pipeline. 3899 3900 // For specific pipelines, e.g. generic RISC-V, define the stages of that pipeline 3901 //pipe_desc(ID, EX, MEM, WR); 3902 #define ID S0 3903 #define EX S1 3904 #define MEM S2 3905 #define WR S3 3906 3907 // Integer ALU reg operation 3908 pipeline %{ 3909 3910 attributes %{ 3911 // RISC-V instructions are of fixed length 3912 fixed_size_instructions; // Fixed size instructions TODO does 3913 max_instructions_per_bundle = 2; // Generic RISC-V 1, Sifive Series 7 2 3914 // RISC-V instructions come in 32-bit word units 3915 instruction_unit_size = 4; // An instruction is 4 bytes long 3916 instruction_fetch_unit_size = 64; // The processor fetches one line 3917 instruction_fetch_units = 1; // of 64 bytes 3918 3919 // List of nop instructions 3920 nops( MachNop ); 3921 %} 3922 3923 // We don't use an actual pipeline model so don't care about resources 3924 // or description. we do use pipeline classes to introduce fixed 3925 // latencies 3926 3927 //----------RESOURCES---------------------------------------------------------- 3928 // Resources are the functional units available to the machine 3929 3930 // Generic RISC-V pipeline 3931 // 1 decoder 3932 // 1 instruction decoded per cycle 3933 // 1 load/store ops per cycle, 1 branch, 1 FPU 3934 // 1 mul, 1 div 3935 3936 resources ( DECODE, 3937 ALU, 3938 MUL, 3939 DIV, 3940 BRANCH, 3941 LDST, 3942 FPU); 3943 3944 //----------PIPELINE DESCRIPTION----------------------------------------------- 3945 // Pipeline Description specifies the stages in the machine's pipeline 3946 3947 // Define the pipeline as a generic 6 stage pipeline 3948 pipe_desc(S0, S1, S2, S3, S4, S5); 3949 3950 //----------PIPELINE CLASSES--------------------------------------------------- 3951 // Pipeline Classes describe the stages in which input and output are 3952 // referenced by the hardware pipeline. 3953 3954 pipe_class fp_dop_reg_reg_s(fRegF dst, fRegF src1, fRegF src2) 3955 %{ 3956 single_instruction; 3957 src1 : S1(read); 3958 src2 : S2(read); 3959 dst : S5(write); 3960 DECODE : ID; 3961 FPU : S5; 3962 %} 3963 3964 pipe_class fp_dop_reg_reg_d(fRegD dst, fRegD src1, fRegD src2) 3965 %{ 3966 src1 : S1(read); 3967 src2 : S2(read); 3968 dst : S5(write); 3969 DECODE : ID; 3970 FPU : S5; 3971 %} 3972 3973 pipe_class fp_uop_s(fRegF dst, fRegF src) 3974 %{ 3975 single_instruction; 3976 src : S1(read); 3977 dst : S5(write); 3978 DECODE : ID; 3979 FPU : S5; 3980 %} 3981 3982 pipe_class fp_uop_d(fRegD dst, fRegD src) 3983 %{ 3984 single_instruction; 3985 src : S1(read); 3986 dst : S5(write); 3987 DECODE : ID; 3988 FPU : S5; 3989 %} 3990 3991 pipe_class fp_d2f(fRegF dst, fRegD src) 3992 %{ 3993 single_instruction; 3994 src : S1(read); 3995 dst : S5(write); 3996 DECODE : ID; 3997 FPU : S5; 3998 %} 3999 4000 pipe_class fp_f2d(fRegD dst, fRegF src) 4001 %{ 4002 single_instruction; 4003 src : S1(read); 4004 dst : S5(write); 4005 DECODE : ID; 4006 FPU : S5; 4007 %} 4008 4009 pipe_class fp_f2i(iRegINoSp dst, fRegF src) 4010 %{ 4011 single_instruction; 4012 src : S1(read); 4013 dst : S5(write); 4014 DECODE : ID; 4015 FPU : S5; 4016 %} 4017 4018 pipe_class fp_f2l(iRegLNoSp dst, fRegF src) 4019 %{ 4020 single_instruction; 4021 src : S1(read); 4022 dst : S5(write); 4023 DECODE : ID; 4024 FPU : S5; 4025 %} 4026 4027 pipe_class fp_i2f(fRegF dst, iRegIorL2I src) 4028 %{ 4029 single_instruction; 4030 src : S1(read); 4031 dst : S5(write); 4032 DECODE : ID; 4033 FPU : S5; 4034 %} 4035 4036 pipe_class fp_l2f(fRegF dst, iRegL src) 4037 %{ 4038 single_instruction; 4039 src : S1(read); 4040 dst : S5(write); 4041 DECODE : ID; 4042 FPU : S5; 4043 %} 4044 4045 pipe_class fp_d2i(iRegINoSp dst, fRegD src) 4046 %{ 4047 single_instruction; 4048 src : S1(read); 4049 dst : S5(write); 4050 DECODE : ID; 4051 FPU : S5; 4052 %} 4053 4054 pipe_class fp_d2l(iRegLNoSp dst, fRegD src) 4055 %{ 4056 single_instruction; 4057 src : S1(read); 4058 dst : S5(write); 4059 DECODE : ID; 4060 FPU : S5; 4061 %} 4062 4063 pipe_class fp_i2d(fRegD dst, iRegIorL2I src) 4064 %{ 4065 single_instruction; 4066 src : S1(read); 4067 dst : S5(write); 4068 DECODE : ID; 4069 FPU : S5; 4070 %} 4071 4072 pipe_class fp_l2d(fRegD dst, iRegIorL2I src) 4073 %{ 4074 single_instruction; 4075 src : S1(read); 4076 dst : S5(write); 4077 DECODE : ID; 4078 FPU : S5; 4079 %} 4080 4081 pipe_class fp_div_s(fRegF dst, fRegF src1, fRegF src2) 4082 %{ 4083 single_instruction; 4084 src1 : S1(read); 4085 src2 : S2(read); 4086 dst : S5(write); 4087 DECODE : ID; 4088 FPU : S5; 4089 %} 4090 4091 pipe_class fp_div_d(fRegD dst, fRegD src1, fRegD src2) 4092 %{ 4093 single_instruction; 4094 src1 : S1(read); 4095 src2 : S2(read); 4096 dst : S5(write); 4097 DECODE : ID; 4098 FPU : S5; 4099 %} 4100 4101 pipe_class fp_sqrt_s(fRegF dst, fRegF src1, fRegF src2) 4102 %{ 4103 single_instruction; 4104 src1 : S1(read); 4105 src2 : S2(read); 4106 dst : S5(write); 4107 DECODE : ID; 4108 FPU : S5; 4109 %} 4110 4111 pipe_class fp_sqrt_d(fRegD dst, fRegD src1, fRegD src2) 4112 %{ 4113 single_instruction; 4114 src1 : S1(read); 4115 src2 : S2(read); 4116 dst : S5(write); 4117 DECODE : ID; 4118 FPU : S5; 4119 %} 4120 4121 pipe_class fp_load_constant_s(fRegF dst) 4122 %{ 4123 single_instruction; 4124 dst : S5(write); 4125 DECODE : ID; 4126 FPU : S5; 4127 %} 4128 4129 pipe_class fp_load_constant_d(fRegD dst) 4130 %{ 4131 single_instruction; 4132 dst : S5(write); 4133 DECODE : ID; 4134 FPU : S5; 4135 %} 4136 4137 pipe_class fp_load_mem_s(fRegF dst, memory mem) 4138 %{ 4139 single_instruction; 4140 mem : S1(read); 4141 dst : S5(write); 4142 DECODE : ID; 4143 LDST : MEM; 4144 %} 4145 4146 pipe_class fp_load_mem_d(fRegD dst, memory mem) 4147 %{ 4148 single_instruction; 4149 mem : S1(read); 4150 dst : S5(write); 4151 DECODE : ID; 4152 LDST : MEM; 4153 %} 4154 4155 pipe_class fp_store_reg_s(fRegF src, memory mem) 4156 %{ 4157 single_instruction; 4158 src : S1(read); 4159 mem : S5(write); 4160 DECODE : ID; 4161 LDST : MEM; 4162 %} 4163 4164 pipe_class fp_store_reg_d(fRegD src, memory mem) 4165 %{ 4166 single_instruction; 4167 src : S1(read); 4168 mem : S5(write); 4169 DECODE : ID; 4170 LDST : MEM; 4171 %} 4172 4173 //------- Integer ALU operations -------------------------- 4174 4175 // Integer ALU reg-reg operation 4176 // Operands needs in ID, result generated in EX 4177 // E.g. ADD Rd, Rs1, Rs2 4178 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4179 %{ 4180 single_instruction; 4181 dst : EX(write); 4182 src1 : ID(read); 4183 src2 : ID(read); 4184 DECODE : ID; 4185 ALU : EX; 4186 %} 4187 4188 // Integer ALU reg operation with constant shift 4189 // E.g. SLLI Rd, Rs1, #shift 4190 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 4191 %{ 4192 single_instruction; 4193 dst : EX(write); 4194 src1 : ID(read); 4195 DECODE : ID; 4196 ALU : EX; 4197 %} 4198 4199 // Integer ALU reg-reg operation with variable shift 4200 // both operands must be available in ID 4201 // E.g. SLL Rd, Rs1, Rs2 4202 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 4203 %{ 4204 single_instruction; 4205 dst : EX(write); 4206 src1 : ID(read); 4207 src2 : ID(read); 4208 DECODE : ID; 4209 ALU : EX; 4210 %} 4211 4212 // Integer ALU reg operation 4213 // E.g. NEG Rd, Rs2 4214 pipe_class ialu_reg(iRegI dst, iRegI src) 4215 %{ 4216 single_instruction; 4217 dst : EX(write); 4218 src : ID(read); 4219 DECODE : ID; 4220 ALU : EX; 4221 %} 4222 4223 // Integer ALU reg immediate operation 4224 // E.g. ADDI Rd, Rs1, #imm 4225 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 4226 %{ 4227 single_instruction; 4228 dst : EX(write); 4229 src1 : ID(read); 4230 DECODE : ID; 4231 ALU : EX; 4232 %} 4233 4234 // Integer ALU immediate operation (no source operands) 4235 // E.g. LI Rd, #imm 4236 pipe_class ialu_imm(iRegI dst) 4237 %{ 4238 single_instruction; 4239 dst : EX(write); 4240 DECODE : ID; 4241 ALU : EX; 4242 %} 4243 4244 //------- Multiply pipeline operations -------------------- 4245 4246 // Multiply reg-reg 4247 // E.g. MULW Rd, Rs1, Rs2 4248 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4249 %{ 4250 single_instruction; 4251 dst : WR(write); 4252 src1 : ID(read); 4253 src2 : ID(read); 4254 DECODE : ID; 4255 MUL : WR; 4256 %} 4257 4258 // E.g. MUL RD, Rs1, Rs2 4259 pipe_class lmul_reg_reg(iRegL dst, iRegL src1, iRegL src2) 4260 %{ 4261 single_instruction; 4262 fixed_latency(3); // Maximum latency for 64 bit mul 4263 dst : WR(write); 4264 src1 : ID(read); 4265 src2 : ID(read); 4266 DECODE : ID; 4267 MUL : WR; 4268 %} 4269 4270 //------- Divide pipeline operations -------------------- 4271 4272 // E.g. DIVW Rd, Rs1, Rs2 4273 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4274 %{ 4275 single_instruction; 4276 fixed_latency(8); // Maximum latency for 32 bit divide 4277 dst : WR(write); 4278 src1 : ID(read); 4279 src2 : ID(read); 4280 DECODE : ID; 4281 DIV : WR; 4282 %} 4283 4284 // E.g. DIV RD, Rs1, Rs2 4285 pipe_class ldiv_reg_reg(iRegL dst, iRegL src1, iRegL src2) 4286 %{ 4287 single_instruction; 4288 fixed_latency(16); // Maximum latency for 64 bit divide 4289 dst : WR(write); 4290 src1 : ID(read); 4291 src2 : ID(read); 4292 DECODE : ID; 4293 DIV : WR; 4294 %} 4295 4296 //------- Load pipeline operations ------------------------ 4297 4298 // Load - prefetch 4299 // Eg. PREFETCH_W mem 4300 pipe_class iload_prefetch(memory mem) 4301 %{ 4302 single_instruction; 4303 mem : ID(read); 4304 DECODE : ID; 4305 LDST : MEM; 4306 %} 4307 4308 // Load - reg, mem 4309 // E.g. LA Rd, mem 4310 pipe_class iload_reg_mem(iRegI dst, memory mem) 4311 %{ 4312 single_instruction; 4313 dst : WR(write); 4314 mem : ID(read); 4315 DECODE : ID; 4316 LDST : MEM; 4317 %} 4318 4319 // Load - reg, reg 4320 // E.g. LD Rd, Rs 4321 pipe_class iload_reg_reg(iRegI dst, iRegI src) 4322 %{ 4323 single_instruction; 4324 dst : WR(write); 4325 src : ID(read); 4326 DECODE : ID; 4327 LDST : MEM; 4328 %} 4329 4330 //------- Store pipeline operations ----------------------- 4331 4332 // Store - zr, mem 4333 // E.g. SD zr, mem 4334 pipe_class istore_mem(memory mem) 4335 %{ 4336 single_instruction; 4337 mem : ID(read); 4338 DECODE : ID; 4339 LDST : MEM; 4340 %} 4341 4342 // Store - reg, mem 4343 // E.g. SD Rs, mem 4344 pipe_class istore_reg_mem(iRegI src, memory mem) 4345 %{ 4346 single_instruction; 4347 mem : ID(read); 4348 src : EX(read); 4349 DECODE : ID; 4350 LDST : MEM; 4351 %} 4352 4353 // Store - reg, reg 4354 // E.g. SD Rs2, Rs1 4355 pipe_class istore_reg_reg(iRegI dst, iRegI src) 4356 %{ 4357 single_instruction; 4358 dst : ID(read); 4359 src : EX(read); 4360 DECODE : ID; 4361 LDST : MEM; 4362 %} 4363 4364 //------- Control transfer pipeline operations ------------ 4365 4366 // Branch 4367 pipe_class pipe_branch() 4368 %{ 4369 single_instruction; 4370 DECODE : ID; 4371 BRANCH : EX; 4372 %} 4373 4374 // Branch 4375 pipe_class pipe_branch_reg(iRegI src) 4376 %{ 4377 single_instruction; 4378 src : ID(read); 4379 DECODE : ID; 4380 BRANCH : EX; 4381 %} 4382 4383 // Compare & Branch 4384 // E.g. BEQ Rs1, Rs2, L 4385 pipe_class pipe_cmp_branch(iRegI src1, iRegI src2) 4386 %{ 4387 single_instruction; 4388 src1 : ID(read); 4389 src2 : ID(read); 4390 DECODE : ID; 4391 BRANCH : EX; 4392 %} 4393 4394 // E.g. BEQZ Rs, L 4395 pipe_class pipe_cmpz_branch(iRegI src) 4396 %{ 4397 single_instruction; 4398 src : ID(read); 4399 DECODE : ID; 4400 BRANCH : EX; 4401 %} 4402 4403 //------- Synchronisation operations ---------------------- 4404 // Any operation requiring serialization 4405 // E.g. FENCE/Atomic Ops/Load Acquire/Store Release 4406 pipe_class pipe_serial() 4407 %{ 4408 single_instruction; 4409 force_serialization; 4410 fixed_latency(16); 4411 DECODE : ID; 4412 LDST : MEM; 4413 %} 4414 4415 pipe_class pipe_slow() 4416 %{ 4417 instruction_count(10); 4418 multiple_bundles; 4419 force_serialization; 4420 fixed_latency(16); 4421 DECODE : ID; 4422 LDST : MEM; 4423 %} 4424 4425 // Empty pipeline class 4426 pipe_class pipe_class_empty() 4427 %{ 4428 single_instruction; 4429 fixed_latency(0); 4430 %} 4431 4432 // Default pipeline class. 4433 pipe_class pipe_class_default() 4434 %{ 4435 single_instruction; 4436 fixed_latency(2); 4437 %} 4438 4439 // Pipeline class for compares. 4440 pipe_class pipe_class_compare() 4441 %{ 4442 single_instruction; 4443 fixed_latency(16); 4444 %} 4445 4446 // Pipeline class for memory operations. 4447 pipe_class pipe_class_memory() 4448 %{ 4449 single_instruction; 4450 fixed_latency(16); 4451 %} 4452 4453 // Pipeline class for call. 4454 pipe_class pipe_class_call() 4455 %{ 4456 single_instruction; 4457 fixed_latency(100); 4458 %} 4459 4460 // Define the class for the Nop node. 4461 define %{ 4462 MachNop = pipe_class_empty; 4463 %} 4464 %} 4465 //----------INSTRUCTIONS------------------------------------------------------- 4466 // 4467 // match -- States which machine-independent subtree may be replaced 4468 // by this instruction. 4469 // ins_cost -- The estimated cost of this instruction is used by instruction 4470 // selection to identify a minimum cost tree of machine 4471 // instructions that matches a tree of machine-independent 4472 // instructions. 4473 // format -- A string providing the disassembly for this instruction. 4474 // The value of an instruction's operand may be inserted 4475 // by referring to it with a '$' prefix. 4476 // opcode -- Three instruction opcodes may be provided. These are referred 4477 // to within an encode class as $primary, $secondary, and $tertiary 4478 // rrspectively. The primary opcode is commonly used to 4479 // indicate the type of machine instruction, while secondary 4480 // and tertiary are often used for prefix options or addressing 4481 // modes. 4482 // ins_encode -- A list of encode classes with parameters. The encode class 4483 // name must have been defined in an 'enc_class' specification 4484 // in the encode section of the architecture description. 4485 4486 // ============================================================================ 4487 // Memory (Load/Store) Instructions 4488 4489 // Load Instructions 4490 4491 // Load Byte (8 bit signed) 4492 instruct loadB(iRegINoSp dst, memory mem) 4493 %{ 4494 match(Set dst (LoadB mem)); 4495 4496 ins_cost(LOAD_COST); 4497 format %{ "lb $dst, $mem\t# byte, #@loadB" %} 4498 4499 ins_encode %{ 4500 __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4501 %} 4502 4503 ins_pipe(iload_reg_mem); 4504 %} 4505 4506 // Load Byte (8 bit signed) into long 4507 instruct loadB2L(iRegLNoSp dst, memory mem) 4508 %{ 4509 match(Set dst (ConvI2L (LoadB mem))); 4510 4511 ins_cost(LOAD_COST); 4512 format %{ "lb $dst, $mem\t# byte, #@loadB2L" %} 4513 4514 ins_encode %{ 4515 __ lb(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4516 %} 4517 4518 ins_pipe(iload_reg_mem); 4519 %} 4520 4521 // Load Byte (8 bit unsigned) 4522 instruct loadUB(iRegINoSp dst, memory mem) 4523 %{ 4524 match(Set dst (LoadUB mem)); 4525 4526 ins_cost(LOAD_COST); 4527 format %{ "lbu $dst, $mem\t# byte, #@loadUB" %} 4528 4529 ins_encode %{ 4530 __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4531 %} 4532 4533 ins_pipe(iload_reg_mem); 4534 %} 4535 4536 // Load Byte (8 bit unsigned) into long 4537 instruct loadUB2L(iRegLNoSp dst, memory mem) 4538 %{ 4539 match(Set dst (ConvI2L (LoadUB mem))); 4540 4541 ins_cost(LOAD_COST); 4542 format %{ "lbu $dst, $mem\t# byte, #@loadUB2L" %} 4543 4544 ins_encode %{ 4545 __ lbu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4546 %} 4547 4548 ins_pipe(iload_reg_mem); 4549 %} 4550 4551 // Load Short (16 bit signed) 4552 instruct loadS(iRegINoSp dst, memory mem) 4553 %{ 4554 match(Set dst (LoadS mem)); 4555 4556 ins_cost(LOAD_COST); 4557 format %{ "lh $dst, $mem\t# short, #@loadS" %} 4558 4559 ins_encode %{ 4560 __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4561 %} 4562 4563 ins_pipe(iload_reg_mem); 4564 %} 4565 4566 // Load Short (16 bit signed) into long 4567 instruct loadS2L(iRegLNoSp dst, memory mem) 4568 %{ 4569 match(Set dst (ConvI2L (LoadS mem))); 4570 4571 ins_cost(LOAD_COST); 4572 format %{ "lh $dst, $mem\t# short, #@loadS2L" %} 4573 4574 ins_encode %{ 4575 __ lh(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4576 %} 4577 4578 ins_pipe(iload_reg_mem); 4579 %} 4580 4581 // Load Char (16 bit unsigned) 4582 instruct loadUS(iRegINoSp dst, memory mem) 4583 %{ 4584 match(Set dst (LoadUS mem)); 4585 4586 ins_cost(LOAD_COST); 4587 format %{ "lhu $dst, $mem\t# short, #@loadUS" %} 4588 4589 ins_encode %{ 4590 __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4591 %} 4592 4593 ins_pipe(iload_reg_mem); 4594 %} 4595 4596 // Load Short/Char (16 bit unsigned) into long 4597 instruct loadUS2L(iRegLNoSp dst, memory mem) 4598 %{ 4599 match(Set dst (ConvI2L (LoadUS mem))); 4600 4601 ins_cost(LOAD_COST); 4602 format %{ "lhu $dst, $mem\t# short, #@loadUS2L" %} 4603 4604 ins_encode %{ 4605 __ lhu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4606 %} 4607 4608 ins_pipe(iload_reg_mem); 4609 %} 4610 4611 // Load Integer (32 bit signed) 4612 instruct loadI(iRegINoSp dst, memory mem) 4613 %{ 4614 match(Set dst (LoadI mem)); 4615 4616 ins_cost(LOAD_COST); 4617 format %{ "lw $dst, $mem\t# int, #@loadI" %} 4618 4619 ins_encode %{ 4620 __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4621 %} 4622 4623 ins_pipe(iload_reg_mem); 4624 %} 4625 4626 // Load Integer (32 bit signed) into long 4627 instruct loadI2L(iRegLNoSp dst, memory mem) 4628 %{ 4629 match(Set dst (ConvI2L (LoadI mem))); 4630 4631 ins_cost(LOAD_COST); 4632 format %{ "lw $dst, $mem\t# int, #@loadI2L" %} 4633 4634 ins_encode %{ 4635 __ lw(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4636 %} 4637 4638 ins_pipe(iload_reg_mem); 4639 %} 4640 4641 // Load Integer (32 bit unsigned) into long 4642 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 4643 %{ 4644 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4645 4646 ins_cost(LOAD_COST); 4647 format %{ "lwu $dst, $mem\t# int, #@loadUI2L" %} 4648 4649 ins_encode %{ 4650 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4651 %} 4652 4653 ins_pipe(iload_reg_mem); 4654 %} 4655 4656 // Load Long (64 bit signed) 4657 instruct loadL(iRegLNoSp dst, memory mem) 4658 %{ 4659 match(Set dst (LoadL mem)); 4660 4661 ins_cost(LOAD_COST); 4662 format %{ "ld $dst, $mem\t# int, #@loadL" %} 4663 4664 ins_encode %{ 4665 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4666 %} 4667 4668 ins_pipe(iload_reg_mem); 4669 %} 4670 4671 // Load Range 4672 instruct loadRange(iRegINoSp dst, memory mem) 4673 %{ 4674 match(Set dst (LoadRange mem)); 4675 4676 ins_cost(LOAD_COST); 4677 format %{ "lwu $dst, $mem\t# range, #@loadRange" %} 4678 4679 ins_encode %{ 4680 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4681 %} 4682 4683 ins_pipe(iload_reg_mem); 4684 %} 4685 4686 // Load Pointer 4687 instruct loadP(iRegPNoSp dst, memory mem) 4688 %{ 4689 match(Set dst (LoadP mem)); 4690 predicate(n->as_Load()->barrier_data() == 0); 4691 4692 ins_cost(LOAD_COST); 4693 format %{ "ld $dst, $mem\t# ptr, #@loadP" %} 4694 4695 ins_encode %{ 4696 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4697 %} 4698 4699 ins_pipe(iload_reg_mem); 4700 %} 4701 4702 // Load Compressed Pointer 4703 instruct loadN(iRegNNoSp dst, memory mem) 4704 %{ 4705 match(Set dst (LoadN mem)); 4706 4707 ins_cost(LOAD_COST); 4708 format %{ "lwu $dst, $mem\t# loadN, compressed ptr, #@loadN" %} 4709 4710 ins_encode %{ 4711 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4712 %} 4713 4714 ins_pipe(iload_reg_mem); 4715 %} 4716 4717 // Load Klass Pointer 4718 instruct loadKlass(iRegPNoSp dst, memory mem) 4719 %{ 4720 match(Set dst (LoadKlass mem)); 4721 4722 ins_cost(LOAD_COST); 4723 format %{ "ld $dst, $mem\t# class, #@loadKlass" %} 4724 4725 ins_encode %{ 4726 __ ld(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4727 %} 4728 4729 ins_pipe(iload_reg_mem); 4730 %} 4731 4732 // Load Narrow Klass Pointer 4733 instruct loadNKlass(iRegNNoSp dst, memory mem) 4734 %{ 4735 match(Set dst (LoadNKlass mem)); 4736 4737 ins_cost(LOAD_COST); 4738 format %{ "lwu $dst, $mem\t# loadNKlass, compressed class ptr, #@loadNKlass" %} 4739 4740 ins_encode %{ 4741 __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4742 %} 4743 4744 ins_pipe(iload_reg_mem); 4745 %} 4746 4747 // Load Float 4748 instruct loadF(fRegF dst, memory mem) 4749 %{ 4750 match(Set dst (LoadF mem)); 4751 4752 ins_cost(LOAD_COST); 4753 format %{ "flw $dst, $mem\t# float, #@loadF" %} 4754 4755 ins_encode %{ 4756 __ flw(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4757 %} 4758 4759 ins_pipe(fp_load_mem_s); 4760 %} 4761 4762 // Load Double 4763 instruct loadD(fRegD dst, memory mem) 4764 %{ 4765 match(Set dst (LoadD mem)); 4766 4767 ins_cost(LOAD_COST); 4768 format %{ "fld $dst, $mem\t# double, #@loadD" %} 4769 4770 ins_encode %{ 4771 __ fld(as_FloatRegister($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4772 %} 4773 4774 ins_pipe(fp_load_mem_d); 4775 %} 4776 4777 // Load Int Constant 4778 instruct loadConI(iRegINoSp dst, immI src) 4779 %{ 4780 match(Set dst src); 4781 4782 ins_cost(ALU_COST); 4783 format %{ "mv $dst, $src\t# int, #@loadConI" %} 4784 4785 ins_encode(riscv_enc_mov_imm(dst, src)); 4786 4787 ins_pipe(ialu_imm); 4788 %} 4789 4790 // Load Long Constant 4791 instruct loadConL(iRegLNoSp dst, immL src) 4792 %{ 4793 match(Set dst src); 4794 4795 ins_cost(ALU_COST); 4796 format %{ "mv $dst, $src\t# long, #@loadConL" %} 4797 4798 ins_encode(riscv_enc_mov_imm(dst, src)); 4799 4800 ins_pipe(ialu_imm); 4801 %} 4802 4803 // Load Pointer Constant 4804 instruct loadConP(iRegPNoSp dst, immP con) 4805 %{ 4806 match(Set dst con); 4807 4808 ins_cost(ALU_COST); 4809 format %{ "mv $dst, $con\t# ptr, #@loadConP" %} 4810 4811 ins_encode(riscv_enc_mov_p(dst, con)); 4812 4813 ins_pipe(ialu_imm); 4814 %} 4815 4816 // Load Null Pointer Constant 4817 instruct loadConP0(iRegPNoSp dst, immP0 con) 4818 %{ 4819 match(Set dst con); 4820 4821 ins_cost(ALU_COST); 4822 format %{ "mv $dst, $con\t# NULL ptr, #@loadConP0" %} 4823 4824 ins_encode(riscv_enc_mov_zero(dst)); 4825 4826 ins_pipe(ialu_imm); 4827 %} 4828 4829 // Load Pointer Constant One 4830 instruct loadConP1(iRegPNoSp dst, immP_1 con) 4831 %{ 4832 match(Set dst con); 4833 4834 ins_cost(ALU_COST); 4835 format %{ "mv $dst, $con\t# load ptr constant one, #@loadConP1" %} 4836 4837 ins_encode(riscv_enc_mov_p1(dst)); 4838 4839 ins_pipe(ialu_imm); 4840 %} 4841 4842 // Load Byte Map Base Constant 4843 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 4844 %{ 4845 match(Set dst con); 4846 ins_cost(ALU_COST); 4847 format %{ "mv $dst, $con\t# Byte Map Base, #@loadByteMapBase" %} 4848 4849 ins_encode(riscv_enc_mov_byte_map_base(dst)); 4850 4851 ins_pipe(ialu_imm); 4852 %} 4853 4854 // Load Narrow Pointer Constant 4855 instruct loadConN(iRegNNoSp dst, immN con) 4856 %{ 4857 match(Set dst con); 4858 4859 ins_cost(ALU_COST * 4); 4860 format %{ "mv $dst, $con\t# compressed ptr, #@loadConN" %} 4861 4862 ins_encode(riscv_enc_mov_n(dst, con)); 4863 4864 ins_pipe(ialu_imm); 4865 %} 4866 4867 // Load Narrow Null Pointer Constant 4868 instruct loadConN0(iRegNNoSp dst, immN0 con) 4869 %{ 4870 match(Set dst con); 4871 4872 ins_cost(ALU_COST); 4873 format %{ "mv $dst, $con\t# compressed NULL ptr, #@loadConN0" %} 4874 4875 ins_encode(riscv_enc_mov_zero(dst)); 4876 4877 ins_pipe(ialu_imm); 4878 %} 4879 4880 // Load Narrow Klass Constant 4881 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 4882 %{ 4883 match(Set dst con); 4884 4885 ins_cost(ALU_COST * 6); 4886 format %{ "mv $dst, $con\t# compressed klass ptr, #@loadConNKlass" %} 4887 4888 ins_encode(riscv_enc_mov_nk(dst, con)); 4889 4890 ins_pipe(ialu_imm); 4891 %} 4892 4893 // Load Float Constant 4894 instruct loadConF(fRegF dst, immF con) %{ 4895 match(Set dst con); 4896 4897 ins_cost(LOAD_COST); 4898 format %{ 4899 "flw $dst, [$constantaddress]\t# load from constant table: float=$con, #@loadConF" 4900 %} 4901 4902 ins_encode %{ 4903 __ flw(as_FloatRegister($dst$$reg), $constantaddress($con)); 4904 %} 4905 4906 ins_pipe(fp_load_constant_s); 4907 %} 4908 4909 instruct loadConF0(fRegF dst, immF0 con) %{ 4910 match(Set dst con); 4911 4912 ins_cost(XFER_COST); 4913 4914 format %{ "fmv.w.x $dst, zr\t# float, #@loadConF0" %} 4915 4916 ins_encode %{ 4917 __ fmv_w_x(as_FloatRegister($dst$$reg), zr); 4918 %} 4919 4920 ins_pipe(fp_load_constant_s); 4921 %} 4922 4923 // Load Double Constant 4924 instruct loadConD(fRegD dst, immD con) %{ 4925 match(Set dst con); 4926 4927 ins_cost(LOAD_COST); 4928 format %{ 4929 "fld $dst, [$constantaddress]\t# load from constant table: double=$con, #@loadConD" 4930 %} 4931 4932 ins_encode %{ 4933 __ fld(as_FloatRegister($dst$$reg), $constantaddress($con)); 4934 %} 4935 4936 ins_pipe(fp_load_constant_d); 4937 %} 4938 4939 instruct loadConD0(fRegD dst, immD0 con) %{ 4940 match(Set dst con); 4941 4942 ins_cost(XFER_COST); 4943 4944 format %{ "fmv.d.x $dst, zr\t# double, #@loadConD0" %} 4945 4946 ins_encode %{ 4947 __ fmv_d_x(as_FloatRegister($dst$$reg), zr); 4948 %} 4949 4950 ins_pipe(fp_load_constant_d); 4951 %} 4952 4953 // Store Instructions 4954 // Store CMS card-mark Immediate 4955 instruct storeimmCM0(immI0 zero, memory mem) 4956 %{ 4957 match(Set mem (StoreCM mem zero)); 4958 4959 ins_cost(STORE_COST); 4960 format %{ "storestore (elided)\n\t" 4961 "sb zr, $mem\t# byte, #@storeimmCM0" %} 4962 4963 ins_encode %{ 4964 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 4965 %} 4966 4967 ins_pipe(istore_mem); 4968 %} 4969 4970 // Store CMS card-mark Immediate with intervening StoreStore 4971 // needed when using CMS with no conditional card marking 4972 instruct storeimmCM0_ordered(immI0 zero, memory mem) 4973 %{ 4974 match(Set mem (StoreCM mem zero)); 4975 4976 ins_cost(ALU_COST + STORE_COST); 4977 format %{ "membar(StoreStore)\n\t" 4978 "sb zr, $mem\t# byte, #@storeimmCM0_ordered" %} 4979 4980 ins_encode %{ 4981 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 4982 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 4983 %} 4984 4985 ins_pipe(istore_mem); 4986 %} 4987 4988 // Store Byte 4989 instruct storeB(iRegIorL2I src, memory mem) 4990 %{ 4991 match(Set mem (StoreB mem src)); 4992 4993 ins_cost(STORE_COST); 4994 format %{ "sb $src, $mem\t# byte, #@storeB" %} 4995 4996 ins_encode %{ 4997 __ sb(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 4998 %} 4999 5000 ins_pipe(istore_reg_mem); 5001 %} 5002 5003 instruct storeimmB0(immI0 zero, memory mem) 5004 %{ 5005 match(Set mem (StoreB mem zero)); 5006 5007 ins_cost(STORE_COST); 5008 format %{ "sb zr, $mem\t# byte, #@storeimmB0" %} 5009 5010 ins_encode %{ 5011 __ sb(zr, Address(as_Register($mem$$base), $mem$$disp)); 5012 %} 5013 5014 ins_pipe(istore_mem); 5015 %} 5016 5017 // Store Char/Short 5018 instruct storeC(iRegIorL2I src, memory mem) 5019 %{ 5020 match(Set mem (StoreC mem src)); 5021 5022 ins_cost(STORE_COST); 5023 format %{ "sh $src, $mem\t# short, #@storeC" %} 5024 5025 ins_encode %{ 5026 __ sh(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5027 %} 5028 5029 ins_pipe(istore_reg_mem); 5030 %} 5031 5032 instruct storeimmC0(immI0 zero, memory mem) 5033 %{ 5034 match(Set mem (StoreC mem zero)); 5035 5036 ins_cost(STORE_COST); 5037 format %{ "sh zr, $mem\t# short, #@storeimmC0" %} 5038 5039 ins_encode %{ 5040 __ sh(zr, Address(as_Register($mem$$base), $mem$$disp)); 5041 %} 5042 5043 ins_pipe(istore_mem); 5044 %} 5045 5046 // Store Integer 5047 instruct storeI(iRegIorL2I src, memory mem) 5048 %{ 5049 match(Set mem(StoreI mem src)); 5050 5051 ins_cost(STORE_COST); 5052 format %{ "sw $src, $mem\t# int, #@storeI" %} 5053 5054 ins_encode %{ 5055 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5056 %} 5057 5058 ins_pipe(istore_reg_mem); 5059 %} 5060 5061 instruct storeimmI0(immI0 zero, memory mem) 5062 %{ 5063 match(Set mem(StoreI mem zero)); 5064 5065 ins_cost(STORE_COST); 5066 format %{ "sw zr, $mem\t# int, #@storeimmI0" %} 5067 5068 ins_encode %{ 5069 __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); 5070 %} 5071 5072 ins_pipe(istore_mem); 5073 %} 5074 5075 // Store Long (64 bit signed) 5076 instruct storeL(iRegL src, memory mem) 5077 %{ 5078 match(Set mem (StoreL mem src)); 5079 5080 ins_cost(STORE_COST); 5081 format %{ "sd $src, $mem\t# long, #@storeL" %} 5082 5083 ins_encode %{ 5084 __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5085 %} 5086 5087 ins_pipe(istore_reg_mem); 5088 %} 5089 5090 // Store Long (64 bit signed) 5091 instruct storeimmL0(immL0 zero, memory mem) 5092 %{ 5093 match(Set mem (StoreL mem zero)); 5094 5095 ins_cost(STORE_COST); 5096 format %{ "sd zr, $mem\t# long, #@storeimmL0" %} 5097 5098 ins_encode %{ 5099 __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); 5100 %} 5101 5102 ins_pipe(istore_mem); 5103 %} 5104 5105 // Store Pointer 5106 instruct storeP(iRegP src, memory mem) 5107 %{ 5108 match(Set mem (StoreP mem src)); 5109 predicate(n->as_Store()->barrier_data() == 0); 5110 5111 ins_cost(STORE_COST); 5112 format %{ "sd $src, $mem\t# ptr, #@storeP" %} 5113 5114 ins_encode %{ 5115 __ sd(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5116 %} 5117 5118 ins_pipe(istore_reg_mem); 5119 %} 5120 5121 // Store Pointer 5122 instruct storeimmP0(immP0 zero, memory mem) 5123 %{ 5124 match(Set mem (StoreP mem zero)); 5125 predicate(n->as_Store()->barrier_data() == 0); 5126 5127 ins_cost(STORE_COST); 5128 format %{ "sd zr, $mem\t# ptr, #@storeimmP0" %} 5129 5130 ins_encode %{ 5131 __ sd(zr, Address(as_Register($mem$$base), $mem$$disp)); 5132 %} 5133 5134 ins_pipe(istore_mem); 5135 %} 5136 5137 // Store Compressed Pointer 5138 instruct storeN(iRegN src, memory mem) 5139 %{ 5140 match(Set mem (StoreN mem src)); 5141 5142 ins_cost(STORE_COST); 5143 format %{ "sw $src, $mem\t# compressed ptr, #@storeN" %} 5144 5145 ins_encode %{ 5146 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5147 %} 5148 5149 ins_pipe(istore_reg_mem); 5150 %} 5151 5152 instruct storeImmN0(immN0 zero, memory mem) 5153 %{ 5154 match(Set mem (StoreN mem zero)); 5155 5156 ins_cost(STORE_COST); 5157 format %{ "sw zr, $mem\t# compressed ptr, #@storeImmN0" %} 5158 5159 ins_encode %{ 5160 __ sw(zr, Address(as_Register($mem$$base), $mem$$disp)); 5161 %} 5162 5163 ins_pipe(istore_reg_mem); 5164 %} 5165 5166 // Store Float 5167 instruct storeF(fRegF src, memory mem) 5168 %{ 5169 match(Set mem (StoreF mem src)); 5170 5171 ins_cost(STORE_COST); 5172 format %{ "fsw $src, $mem\t# float, #@storeF" %} 5173 5174 ins_encode %{ 5175 __ fsw(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5176 %} 5177 5178 ins_pipe(fp_store_reg_s); 5179 %} 5180 5181 // Store Double 5182 instruct storeD(fRegD src, memory mem) 5183 %{ 5184 match(Set mem (StoreD mem src)); 5185 5186 ins_cost(STORE_COST); 5187 format %{ "fsd $src, $mem\t# double, #@storeD" %} 5188 5189 ins_encode %{ 5190 __ fsd(as_FloatRegister($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5191 %} 5192 5193 ins_pipe(fp_store_reg_d); 5194 %} 5195 5196 // Store Compressed Klass Pointer 5197 instruct storeNKlass(iRegN src, memory mem) 5198 %{ 5199 match(Set mem (StoreNKlass mem src)); 5200 5201 ins_cost(STORE_COST); 5202 format %{ "sw $src, $mem\t# compressed klass ptr, #@storeNKlass" %} 5203 5204 ins_encode %{ 5205 __ sw(as_Register($src$$reg), Address(as_Register($mem$$base), $mem$$disp)); 5206 %} 5207 5208 ins_pipe(istore_reg_mem); 5209 %} 5210 5211 // ============================================================================ 5212 // Prefetch instructions 5213 // Must be safe to execute with invalid address (cannot fault). 5214 5215 instruct prefetchalloc( memory mem ) %{ 5216 predicate(UseZicbop); 5217 match(PrefetchAllocation mem); 5218 5219 ins_cost(ALU_COST * 1); 5220 format %{ "prefetch_w $mem\t# Prefetch for write" %} 5221 5222 ins_encode %{ 5223 if (Assembler::is_simm12($mem$$disp)) { 5224 if (($mem$$disp & 0x1f) == 0) { 5225 __ prefetch_w(as_Register($mem$$base), $mem$$disp); 5226 } else { 5227 __ addi(t0, as_Register($mem$$base), $mem$$disp); 5228 __ prefetch_w(t0, 0); 5229 } 5230 } else { 5231 __ mv(t0, $mem$$disp); 5232 __ add(t0, as_Register($mem$$base), t0); 5233 __ prefetch_w(t0, 0); 5234 } 5235 %} 5236 5237 ins_pipe(iload_prefetch); 5238 %} 5239 5240 // ============================================================================ 5241 // Atomic operation instructions 5242 // 5243 5244 // standard CompareAndSwapX when we are using barriers 5245 // these have higher priority than the rules selected by a predicate 5246 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5247 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5248 %{ 5249 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 5250 5251 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); 5252 5253 effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 5254 5255 format %{ 5256 "cmpxchg $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" 5257 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapB" 5258 %} 5259 5260 ins_encode %{ 5261 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5262 Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, 5263 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5264 %} 5265 5266 ins_pipe(pipe_slow); 5267 %} 5268 5269 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5270 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5271 %{ 5272 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 5273 5274 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); 5275 5276 effect(TEMP_DEF res, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 5277 5278 format %{ 5279 "cmpxchg $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" 5280 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapS" 5281 %} 5282 5283 ins_encode %{ 5284 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5285 Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, 5286 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5287 %} 5288 5289 ins_pipe(pipe_slow); 5290 %} 5291 5292 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5293 %{ 5294 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 5295 5296 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5297 5298 format %{ 5299 "cmpxchg $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" 5300 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapI" 5301 %} 5302 5303 ins_encode(riscv_enc_cmpxchgw(res, mem, oldval, newval)); 5304 5305 ins_pipe(pipe_slow); 5306 %} 5307 5308 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5309 %{ 5310 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 5311 5312 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5313 5314 format %{ 5315 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" 5316 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapL" 5317 %} 5318 5319 ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); 5320 5321 ins_pipe(pipe_slow); 5322 %} 5323 5324 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5325 %{ 5326 predicate(n->as_LoadStore()->barrier_data() == 0); 5327 5328 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 5329 5330 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5331 5332 format %{ 5333 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" 5334 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapP" 5335 %} 5336 5337 ins_encode(riscv_enc_cmpxchg(res, mem, oldval, newval)); 5338 5339 ins_pipe(pipe_slow); 5340 %} 5341 5342 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5343 %{ 5344 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 5345 5346 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); 5347 5348 format %{ 5349 "cmpxchg $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" 5350 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapN" 5351 %} 5352 5353 ins_encode(riscv_enc_cmpxchgn(res, mem, oldval, newval)); 5354 5355 ins_pipe(pipe_slow); 5356 %} 5357 5358 // alternative CompareAndSwapX when we are eliding barriers 5359 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5360 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5361 %{ 5362 predicate(needs_acquiring_load_reserved(n)); 5363 5364 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 5365 5366 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 10 + BRANCH_COST * 4); 5367 5368 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5369 5370 format %{ 5371 "cmpxchg_acq $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval\n\t" 5372 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapBAcq" 5373 %} 5374 5375 ins_encode %{ 5376 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5377 Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, 5378 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5379 %} 5380 5381 ins_pipe(pipe_slow); 5382 %} 5383 5384 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5385 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5386 %{ 5387 predicate(needs_acquiring_load_reserved(n)); 5388 5389 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 5390 5391 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 11 + BRANCH_COST * 4); 5392 5393 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5394 5395 format %{ 5396 "cmpxchg_acq $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval\n\t" 5397 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapSAcq" 5398 %} 5399 5400 ins_encode %{ 5401 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5402 Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, 5403 true /* result as bool */, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5404 %} 5405 5406 ins_pipe(pipe_slow); 5407 %} 5408 5409 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5410 %{ 5411 predicate(needs_acquiring_load_reserved(n)); 5412 5413 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 5414 5415 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5416 5417 format %{ 5418 "cmpxchg_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval\n\t" 5419 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapIAcq" 5420 %} 5421 5422 ins_encode(riscv_enc_cmpxchgw_acq(res, mem, oldval, newval)); 5423 5424 ins_pipe(pipe_slow); 5425 %} 5426 5427 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5428 %{ 5429 predicate(needs_acquiring_load_reserved(n)); 5430 5431 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 5432 5433 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5434 5435 format %{ 5436 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval\n\t" 5437 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapLAcq" 5438 %} 5439 5440 ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); 5441 5442 ins_pipe(pipe_slow); 5443 %} 5444 5445 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5446 %{ 5447 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 5448 5449 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 5450 5451 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 6 + BRANCH_COST * 4); 5452 5453 format %{ 5454 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval\n\t" 5455 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapPAcq" 5456 %} 5457 5458 ins_encode(riscv_enc_cmpxchg_acq(res, mem, oldval, newval)); 5459 5460 ins_pipe(pipe_slow); 5461 %} 5462 5463 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5464 %{ 5465 predicate(needs_acquiring_load_reserved(n)); 5466 5467 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 5468 5469 ins_cost(LOAD_COST + STORE_COST + ALU_COST * 8 + BRANCH_COST * 4); 5470 5471 format %{ 5472 "cmpxchg_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval\n\t" 5473 "mv $res, $res == $oldval\t# $res <-- ($res == $oldval ? 1 : 0), #@compareAndSwapNAcq" 5474 %} 5475 5476 ins_encode(riscv_enc_cmpxchgn_acq(res, mem, oldval, newval)); 5477 5478 ins_pipe(pipe_slow); 5479 %} 5480 5481 // Sundry CAS operations. Note that release is always true, 5482 // regardless of the memory ordering of the CAS. This is because we 5483 // need the volatile case to be sequentially consistent but there is 5484 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 5485 // can't check the type of memory ordering here, so we always emit a 5486 // sc_d(w) with rl bit set. 5487 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5488 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5489 %{ 5490 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 5491 5492 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); 5493 5494 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5495 5496 format %{ 5497 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeB" 5498 %} 5499 5500 ins_encode %{ 5501 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5502 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5503 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5504 %} 5505 5506 ins_pipe(pipe_slow); 5507 %} 5508 5509 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5510 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5511 %{ 5512 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 5513 5514 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); 5515 5516 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5517 5518 format %{ 5519 "cmpxchg $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeS" 5520 %} 5521 5522 ins_encode %{ 5523 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5524 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5525 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5526 %} 5527 5528 ins_pipe(pipe_slow); 5529 %} 5530 5531 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5532 %{ 5533 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 5534 5535 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5536 5537 effect(TEMP_DEF res); 5538 5539 format %{ 5540 "cmpxchg $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeI" 5541 %} 5542 5543 ins_encode %{ 5544 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5545 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5546 %} 5547 5548 ins_pipe(pipe_slow); 5549 %} 5550 5551 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) 5552 %{ 5553 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 5554 5555 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5556 5557 effect(TEMP_DEF res); 5558 5559 format %{ 5560 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeL" 5561 %} 5562 5563 ins_encode %{ 5564 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5565 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5566 %} 5567 5568 ins_pipe(pipe_slow); 5569 %} 5570 5571 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) 5572 %{ 5573 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 5574 5575 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 3); 5576 5577 effect(TEMP_DEF res); 5578 5579 format %{ 5580 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN" 5581 %} 5582 5583 ins_encode %{ 5584 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5585 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5586 %} 5587 5588 ins_pipe(pipe_slow); 5589 %} 5590 5591 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) 5592 %{ 5593 predicate(n->as_LoadStore()->barrier_data() == 0); 5594 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 5595 5596 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5597 5598 effect(TEMP_DEF res); 5599 5600 format %{ 5601 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeP" 5602 %} 5603 5604 ins_encode %{ 5605 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5606 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5607 %} 5608 5609 ins_pipe(pipe_slow); 5610 %} 5611 5612 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5613 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5614 %{ 5615 predicate(needs_acquiring_load_reserved(n)); 5616 5617 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 5618 5619 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 5); 5620 5621 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5622 5623 format %{ 5624 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeBAcq" 5625 %} 5626 5627 ins_encode %{ 5628 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5629 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5630 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5631 %} 5632 5633 ins_pipe(pipe_slow); 5634 %} 5635 5636 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5637 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5638 %{ 5639 predicate(needs_acquiring_load_reserved(n)); 5640 5641 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 5642 5643 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST * 6); 5644 5645 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5646 5647 format %{ 5648 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeSAcq" 5649 %} 5650 5651 ins_encode %{ 5652 __ cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5653 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5654 /*result_as_bool*/ false, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5655 %} 5656 5657 ins_pipe(pipe_slow); 5658 %} 5659 5660 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5661 %{ 5662 predicate(needs_acquiring_load_reserved(n)); 5663 5664 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 5665 5666 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5667 5668 effect(TEMP_DEF res); 5669 5670 format %{ 5671 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeIAcq" 5672 %} 5673 5674 ins_encode %{ 5675 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5676 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5677 %} 5678 5679 ins_pipe(pipe_slow); 5680 %} 5681 5682 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval) 5683 %{ 5684 predicate(needs_acquiring_load_reserved(n)); 5685 5686 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 5687 5688 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5689 5690 effect(TEMP_DEF res); 5691 5692 format %{ 5693 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeLAcq" 5694 %} 5695 5696 ins_encode %{ 5697 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5698 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5699 %} 5700 5701 ins_pipe(pipe_slow); 5702 %} 5703 5704 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval) 5705 %{ 5706 predicate(needs_acquiring_load_reserved(n)); 5707 5708 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 5709 5710 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5711 5712 effect(TEMP_DEF res); 5713 5714 format %{ 5715 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq" 5716 %} 5717 5718 ins_encode %{ 5719 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5720 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5721 %} 5722 5723 ins_pipe(pipe_slow); 5724 %} 5725 5726 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) 5727 %{ 5728 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 5729 5730 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 5731 5732 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 3 + ALU_COST); 5733 5734 effect(TEMP_DEF res); 5735 5736 format %{ 5737 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq" 5738 %} 5739 5740 ins_encode %{ 5741 __ cmpxchg(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5742 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5743 %} 5744 5745 ins_pipe(pipe_slow); 5746 %} 5747 5748 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5749 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5750 %{ 5751 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 5752 5753 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); 5754 5755 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5756 5757 format %{ 5758 "cmpxchg_weak $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5759 "# $res == 1 when success, #@weakCompareAndSwapB" 5760 %} 5761 5762 ins_encode %{ 5763 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5764 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5765 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5766 %} 5767 5768 ins_pipe(pipe_slow); 5769 %} 5770 5771 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5772 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5773 %{ 5774 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 5775 5776 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); 5777 5778 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5779 5780 format %{ 5781 "cmpxchg_weak $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5782 "# $res == 1 when success, #@weakCompareAndSwapS" 5783 %} 5784 5785 ins_encode %{ 5786 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5787 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register, 5788 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5789 %} 5790 5791 ins_pipe(pipe_slow); 5792 %} 5793 5794 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5795 %{ 5796 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 5797 5798 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5799 5800 format %{ 5801 "cmpxchg_weak $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5802 "# $res == 1 when success, #@weakCompareAndSwapI" 5803 %} 5804 5805 ins_encode %{ 5806 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5807 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5808 %} 5809 5810 ins_pipe(pipe_slow); 5811 %} 5812 5813 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5814 %{ 5815 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 5816 5817 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5818 5819 format %{ 5820 "cmpxchg_weak $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5821 "# $res == 1 when success, #@weakCompareAndSwapL" 5822 %} 5823 5824 ins_encode %{ 5825 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5826 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5827 %} 5828 5829 ins_pipe(pipe_slow); 5830 %} 5831 5832 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5833 %{ 5834 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 5835 5836 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); 5837 5838 format %{ 5839 "cmpxchg_weak $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5840 "# $res == 1 when success, #@weakCompareAndSwapN" 5841 %} 5842 5843 ins_encode %{ 5844 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5845 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5846 %} 5847 5848 ins_pipe(pipe_slow); 5849 %} 5850 5851 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5852 %{ 5853 predicate(n->as_LoadStore()->barrier_data() == 0); 5854 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 5855 5856 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5857 5858 format %{ 5859 "cmpxchg_weak $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5860 "# $res == 1 when success, #@weakCompareAndSwapP" 5861 %} 5862 5863 ins_encode %{ 5864 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5865 /*acquire*/ Assembler::relaxed, /*release*/ Assembler::rl, $res$$Register); 5866 %} 5867 5868 ins_pipe(pipe_slow); 5869 %} 5870 5871 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5872 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5873 %{ 5874 predicate(needs_acquiring_load_reserved(n)); 5875 5876 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 5877 5878 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 6); 5879 5880 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5881 5882 format %{ 5883 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5884 "# $res == 1 when success, #@weakCompareAndSwapBAcq" 5885 %} 5886 5887 ins_encode %{ 5888 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int8, 5889 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5890 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5891 %} 5892 5893 ins_pipe(pipe_slow); 5894 %} 5895 5896 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI_R12 oldval, iRegI_R13 newval, 5897 iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, rFlagsReg cr) 5898 %{ 5899 predicate(needs_acquiring_load_reserved(n)); 5900 5901 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 5902 5903 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 7); 5904 5905 effect(TEMP_DEF res, KILL cr, USE_KILL oldval, USE_KILL newval, TEMP tmp1, TEMP tmp2, TEMP tmp3); 5906 5907 format %{ 5908 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5909 "# $res == 1 when success, #@weakCompareAndSwapSAcq" 5910 %} 5911 5912 ins_encode %{ 5913 __ weak_cmpxchg_narrow_value(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int16, 5914 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register, 5915 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 5916 %} 5917 5918 ins_pipe(pipe_slow); 5919 %} 5920 5921 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval) 5922 %{ 5923 predicate(needs_acquiring_load_reserved(n)); 5924 5925 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 5926 5927 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5928 5929 format %{ 5930 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5931 "# $res == 1 when success, #@weakCompareAndSwapIAcq" 5932 %} 5933 5934 ins_encode %{ 5935 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int32, 5936 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5937 %} 5938 5939 ins_pipe(pipe_slow); 5940 %} 5941 5942 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval) 5943 %{ 5944 predicate(needs_acquiring_load_reserved(n)); 5945 5946 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 5947 5948 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5949 5950 format %{ 5951 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5952 "# $res == 1 when success, #@weakCompareAndSwapLAcq" 5953 %} 5954 5955 ins_encode %{ 5956 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5957 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5958 %} 5959 5960 ins_pipe(pipe_slow); 5961 %} 5962 5963 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval) 5964 %{ 5965 predicate(needs_acquiring_load_reserved(n)); 5966 5967 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 5968 5969 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 4); 5970 5971 format %{ 5972 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5973 "# $res == 1 when success, #@weakCompareAndSwapNAcq" 5974 %} 5975 5976 ins_encode %{ 5977 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::uint32, 5978 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 5979 %} 5980 5981 ins_pipe(pipe_slow); 5982 %} 5983 5984 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval) 5985 %{ 5986 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 5987 5988 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 5989 5990 ins_cost(LOAD_COST + STORE_COST + BRANCH_COST * 2 + ALU_COST * 2); 5991 5992 format %{ 5993 "cmpxchg_weak_acq $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval\n\t" 5994 "\t# $res == 1 when success, #@weakCompareAndSwapPAcq" 5995 %} 5996 5997 ins_encode %{ 5998 __ cmpxchg_weak(as_Register($mem$$base), $oldval$$Register, $newval$$Register, Assembler::int64, 5999 /*acquire*/ Assembler::aq, /*release*/ Assembler::rl, $res$$Register); 6000 %} 6001 6002 ins_pipe(pipe_slow); 6003 %} 6004 6005 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) 6006 %{ 6007 match(Set prev (GetAndSetI mem newv)); 6008 6009 ins_cost(ALU_COST); 6010 6011 format %{ "atomic_xchgw $prev, $newv, [$mem]\t#@get_and_setI" %} 6012 6013 ins_encode %{ 6014 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6015 %} 6016 6017 ins_pipe(pipe_serial); 6018 %} 6019 6020 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) 6021 %{ 6022 match(Set prev (GetAndSetL mem newv)); 6023 6024 ins_cost(ALU_COST); 6025 6026 format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setL" %} 6027 6028 ins_encode %{ 6029 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6030 %} 6031 6032 ins_pipe(pipe_serial); 6033 %} 6034 6035 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) 6036 %{ 6037 match(Set prev (GetAndSetN mem newv)); 6038 6039 ins_cost(ALU_COST); 6040 6041 format %{ "atomic_xchgwu $prev, $newv, [$mem]\t#@get_and_setN" %} 6042 6043 ins_encode %{ 6044 __ atomic_xchgwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6045 %} 6046 6047 ins_pipe(pipe_serial); 6048 %} 6049 6050 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) 6051 %{ 6052 predicate(n->as_LoadStore()->barrier_data() == 0); 6053 match(Set prev (GetAndSetP mem newv)); 6054 6055 ins_cost(ALU_COST); 6056 6057 format %{ "atomic_xchg $prev, $newv, [$mem]\t#@get_and_setP" %} 6058 6059 ins_encode %{ 6060 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6061 %} 6062 6063 ins_pipe(pipe_serial); 6064 %} 6065 6066 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) 6067 %{ 6068 predicate(needs_acquiring_load_reserved(n)); 6069 6070 match(Set prev (GetAndSetI mem newv)); 6071 6072 ins_cost(ALU_COST); 6073 6074 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]\t#@get_and_setIAcq" %} 6075 6076 ins_encode %{ 6077 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6078 %} 6079 6080 ins_pipe(pipe_serial); 6081 %} 6082 6083 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) 6084 %{ 6085 predicate(needs_acquiring_load_reserved(n)); 6086 6087 match(Set prev (GetAndSetL mem newv)); 6088 6089 ins_cost(ALU_COST); 6090 6091 format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setLAcq" %} 6092 6093 ins_encode %{ 6094 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6095 %} 6096 6097 ins_pipe(pipe_serial); 6098 %} 6099 6100 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) 6101 %{ 6102 predicate(needs_acquiring_load_reserved(n)); 6103 6104 match(Set prev (GetAndSetN mem newv)); 6105 6106 ins_cost(ALU_COST); 6107 6108 format %{ "atomic_xchgwu_acq $prev, $newv, [$mem]\t#@get_and_setNAcq" %} 6109 6110 ins_encode %{ 6111 __ atomic_xchgalwu($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6112 %} 6113 6114 ins_pipe(pipe_serial); 6115 %} 6116 6117 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) 6118 %{ 6119 predicate(needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == 0)); 6120 6121 match(Set prev (GetAndSetP mem newv)); 6122 6123 ins_cost(ALU_COST); 6124 6125 format %{ "atomic_xchg_acq $prev, $newv, [$mem]\t#@get_and_setPAcq" %} 6126 6127 ins_encode %{ 6128 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6129 %} 6130 6131 ins_pipe(pipe_serial); 6132 %} 6133 6134 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) 6135 %{ 6136 match(Set newval (GetAndAddL mem incr)); 6137 6138 ins_cost(ALU_COST); 6139 6140 format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addL" %} 6141 6142 ins_encode %{ 6143 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6144 %} 6145 6146 ins_pipe(pipe_serial); 6147 %} 6148 6149 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) 6150 %{ 6151 predicate(n->as_LoadStore()->result_not_used()); 6152 6153 match(Set dummy (GetAndAddL mem incr)); 6154 6155 ins_cost(ALU_COST); 6156 6157 format %{ "get_and_addL [$mem], $incr\t#@get_and_addL_no_res" %} 6158 6159 ins_encode %{ 6160 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 6161 %} 6162 6163 ins_pipe(pipe_serial); 6164 %} 6165 6166 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAdd incr) 6167 %{ 6168 match(Set newval (GetAndAddL mem incr)); 6169 6170 ins_cost(ALU_COST); 6171 6172 format %{ "get_and_addL $newval, [$mem], $incr\t#@get_and_addLi" %} 6173 6174 ins_encode %{ 6175 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6176 %} 6177 6178 ins_pipe(pipe_serial); 6179 %} 6180 6181 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAdd incr) 6182 %{ 6183 predicate(n->as_LoadStore()->result_not_used()); 6184 6185 match(Set dummy (GetAndAddL mem incr)); 6186 6187 ins_cost(ALU_COST); 6188 6189 format %{ "get_and_addL [$mem], $incr\t#@get_and_addLi_no_res" %} 6190 6191 ins_encode %{ 6192 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 6193 %} 6194 6195 ins_pipe(pipe_serial); 6196 %} 6197 6198 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) 6199 %{ 6200 match(Set newval (GetAndAddI mem incr)); 6201 6202 ins_cost(ALU_COST); 6203 6204 format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addI" %} 6205 6206 ins_encode %{ 6207 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6208 %} 6209 6210 ins_pipe(pipe_serial); 6211 %} 6212 6213 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) 6214 %{ 6215 predicate(n->as_LoadStore()->result_not_used()); 6216 6217 match(Set dummy (GetAndAddI mem incr)); 6218 6219 ins_cost(ALU_COST); 6220 6221 format %{ "get_and_addI [$mem], $incr\t#@get_and_addI_no_res" %} 6222 6223 ins_encode %{ 6224 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 6225 %} 6226 6227 ins_pipe(pipe_serial); 6228 %} 6229 6230 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAdd incr) 6231 %{ 6232 match(Set newval (GetAndAddI mem incr)); 6233 6234 ins_cost(ALU_COST); 6235 6236 format %{ "get_and_addI $newval, [$mem], $incr\t#@get_and_addIi" %} 6237 6238 ins_encode %{ 6239 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6240 %} 6241 6242 ins_pipe(pipe_serial); 6243 %} 6244 6245 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAdd incr) 6246 %{ 6247 predicate(n->as_LoadStore()->result_not_used()); 6248 6249 match(Set dummy (GetAndAddI mem incr)); 6250 6251 ins_cost(ALU_COST); 6252 6253 format %{ "get_and_addI [$mem], $incr\t#@get_and_addIi_no_res" %} 6254 6255 ins_encode %{ 6256 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 6257 %} 6258 6259 ins_pipe(pipe_serial); 6260 %} 6261 6262 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) 6263 %{ 6264 predicate(needs_acquiring_load_reserved(n)); 6265 6266 match(Set newval (GetAndAddL mem incr)); 6267 6268 ins_cost(ALU_COST); 6269 6270 format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLAcq" %} 6271 6272 ins_encode %{ 6273 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6274 %} 6275 6276 ins_pipe(pipe_serial); 6277 %} 6278 6279 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 6280 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6281 6282 match(Set dummy (GetAndAddL mem incr)); 6283 6284 ins_cost(ALU_COST); 6285 6286 format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addL_no_resAcq" %} 6287 6288 ins_encode %{ 6289 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 6290 %} 6291 6292 ins_pipe(pipe_serial); 6293 %} 6294 6295 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAdd incr) 6296 %{ 6297 predicate(needs_acquiring_load_reserved(n)); 6298 6299 match(Set newval (GetAndAddL mem incr)); 6300 6301 ins_cost(ALU_COST); 6302 6303 format %{ "get_and_addL_acq $newval, [$mem], $incr\t#@get_and_addLiAcq" %} 6304 6305 ins_encode %{ 6306 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6307 %} 6308 6309 ins_pipe(pipe_serial); 6310 %} 6311 6312 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAdd incr) 6313 %{ 6314 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6315 6316 match(Set dummy (GetAndAddL mem incr)); 6317 6318 ins_cost(ALU_COST); 6319 6320 format %{ "get_and_addL_acq [$mem], $incr\t#@get_and_addLi_no_resAcq" %} 6321 6322 ins_encode %{ 6323 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 6324 %} 6325 6326 ins_pipe(pipe_serial); 6327 %} 6328 6329 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) 6330 %{ 6331 predicate(needs_acquiring_load_reserved(n)); 6332 6333 match(Set newval (GetAndAddI mem incr)); 6334 6335 ins_cost(ALU_COST); 6336 6337 format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIAcq" %} 6338 6339 ins_encode %{ 6340 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6341 %} 6342 6343 ins_pipe(pipe_serial); 6344 %} 6345 6346 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) 6347 %{ 6348 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6349 6350 match(Set dummy (GetAndAddI mem incr)); 6351 6352 ins_cost(ALU_COST); 6353 6354 format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addI_no_resAcq" %} 6355 6356 ins_encode %{ 6357 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 6358 %} 6359 6360 ins_pipe(pipe_serial); 6361 %} 6362 6363 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAdd incr) 6364 %{ 6365 predicate(needs_acquiring_load_reserved(n)); 6366 6367 match(Set newval (GetAndAddI mem incr)); 6368 6369 ins_cost(ALU_COST); 6370 6371 format %{ "get_and_addI_acq $newval, [$mem], $incr\t#@get_and_addIiAcq" %} 6372 6373 ins_encode %{ 6374 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6375 %} 6376 6377 ins_pipe(pipe_serial); 6378 %} 6379 6380 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAdd incr) 6381 %{ 6382 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_reserved(n)); 6383 6384 match(Set dummy (GetAndAddI mem incr)); 6385 6386 ins_cost(ALU_COST); 6387 6388 format %{ "get_and_addI_acq [$mem], $incr\t#@get_and_addIi_no_resAcq" %} 6389 6390 ins_encode %{ 6391 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 6392 %} 6393 6394 ins_pipe(pipe_serial); 6395 %} 6396 6397 // ============================================================================ 6398 // Arithmetic Instructions 6399 // 6400 6401 // Integer Addition 6402 6403 // TODO 6404 // these currently employ operations which do not set CR and hence are 6405 // not flagged as killing CR but we would like to isolate the cases 6406 // where we want to set flags from those where we don't. need to work 6407 // out how to do that. 6408 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6409 match(Set dst (AddI src1 src2)); 6410 6411 ins_cost(ALU_COST); 6412 format %{ "addw $dst, $src1, $src2\t#@addI_reg_reg" %} 6413 6414 ins_encode %{ 6415 __ addw(as_Register($dst$$reg), 6416 as_Register($src1$$reg), 6417 as_Register($src2$$reg)); 6418 %} 6419 6420 ins_pipe(ialu_reg_reg); 6421 %} 6422 6423 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAdd src2) %{ 6424 match(Set dst (AddI src1 src2)); 6425 6426 ins_cost(ALU_COST); 6427 format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm" %} 6428 6429 ins_encode %{ 6430 int32_t con = (int32_t)$src2$$constant; 6431 __ addiw(as_Register($dst$$reg), 6432 as_Register($src1$$reg), 6433 $src2$$constant); 6434 %} 6435 6436 ins_pipe(ialu_reg_imm); 6437 %} 6438 6439 instruct addI_reg_imm_l2i(iRegINoSp dst, iRegL src1, immIAdd src2) %{ 6440 match(Set dst (AddI (ConvL2I src1) src2)); 6441 6442 ins_cost(ALU_COST); 6443 format %{ "addiw $dst, $src1, $src2\t#@addI_reg_imm_l2i" %} 6444 6445 ins_encode %{ 6446 __ addiw(as_Register($dst$$reg), 6447 as_Register($src1$$reg), 6448 $src2$$constant); 6449 %} 6450 6451 ins_pipe(ialu_reg_imm); 6452 %} 6453 6454 // Pointer Addition 6455 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 6456 match(Set dst (AddP src1 src2)); 6457 6458 ins_cost(ALU_COST); 6459 format %{ "add $dst, $src1, $src2\t# ptr, #@addP_reg_reg" %} 6460 6461 ins_encode %{ 6462 __ add(as_Register($dst$$reg), 6463 as_Register($src1$$reg), 6464 as_Register($src2$$reg)); 6465 %} 6466 6467 ins_pipe(ialu_reg_reg); 6468 %} 6469 6470 // If we shift more than 32 bits, we need not convert I2L. 6471 instruct lShiftL_regI_immGE32(iRegLNoSp dst, iRegI src, uimmI6_ge32 scale) %{ 6472 match(Set dst (LShiftL (ConvI2L src) scale)); 6473 ins_cost(ALU_COST); 6474 format %{ "slli $dst, $src, $scale & 63\t#@lShiftL_regI_immGE32" %} 6475 6476 ins_encode %{ 6477 __ slli(as_Register($dst$$reg), as_Register($src$$reg), $scale$$constant & 63); 6478 %} 6479 6480 ins_pipe(ialu_reg_shift); 6481 %} 6482 6483 // Pointer Immediate Addition 6484 // n.b. this needs to be more expensive than using an indirect memory 6485 // operand 6486 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAdd src2) %{ 6487 match(Set dst (AddP src1 src2)); 6488 ins_cost(ALU_COST); 6489 format %{ "addi $dst, $src1, $src2\t# ptr, #@addP_reg_imm" %} 6490 6491 ins_encode %{ 6492 // src2 is imm, so actually call the addi 6493 __ add(as_Register($dst$$reg), 6494 as_Register($src1$$reg), 6495 $src2$$constant); 6496 %} 6497 6498 ins_pipe(ialu_reg_imm); 6499 %} 6500 6501 // Long Addition 6502 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6503 match(Set dst (AddL src1 src2)); 6504 ins_cost(ALU_COST); 6505 format %{ "add $dst, $src1, $src2\t#@addL_reg_reg" %} 6506 6507 ins_encode %{ 6508 __ add(as_Register($dst$$reg), 6509 as_Register($src1$$reg), 6510 as_Register($src2$$reg)); 6511 %} 6512 6513 ins_pipe(ialu_reg_reg); 6514 %} 6515 6516 // No constant pool entries requiredLong Immediate Addition. 6517 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 6518 match(Set dst (AddL src1 src2)); 6519 ins_cost(ALU_COST); 6520 format %{ "addi $dst, $src1, $src2\t#@addL_reg_imm" %} 6521 6522 ins_encode %{ 6523 // src2 is imm, so actually call the addi 6524 __ add(as_Register($dst$$reg), 6525 as_Register($src1$$reg), 6526 $src2$$constant); 6527 %} 6528 6529 ins_pipe(ialu_reg_imm); 6530 %} 6531 6532 // Integer Subtraction 6533 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6534 match(Set dst (SubI src1 src2)); 6535 6536 ins_cost(ALU_COST); 6537 format %{ "subw $dst, $src1, $src2\t#@subI_reg_reg" %} 6538 6539 ins_encode %{ 6540 __ subw(as_Register($dst$$reg), 6541 as_Register($src1$$reg), 6542 as_Register($src2$$reg)); 6543 %} 6544 6545 ins_pipe(ialu_reg_reg); 6546 %} 6547 6548 // Immediate Subtraction 6549 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immISub src2) %{ 6550 match(Set dst (SubI src1 src2)); 6551 6552 ins_cost(ALU_COST); 6553 format %{ "addiw $dst, $src1, -$src2\t#@subI_reg_imm" %} 6554 6555 ins_encode %{ 6556 // src2 is imm, so actually call the addiw 6557 __ subw(as_Register($dst$$reg), 6558 as_Register($src1$$reg), 6559 $src2$$constant); 6560 %} 6561 6562 ins_pipe(ialu_reg_imm); 6563 %} 6564 6565 // Long Subtraction 6566 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6567 match(Set dst (SubL src1 src2)); 6568 ins_cost(ALU_COST); 6569 format %{ "sub $dst, $src1, $src2\t#@subL_reg_reg" %} 6570 6571 ins_encode %{ 6572 __ sub(as_Register($dst$$reg), 6573 as_Register($src1$$reg), 6574 as_Register($src2$$reg)); 6575 %} 6576 6577 ins_pipe(ialu_reg_reg); 6578 %} 6579 6580 // No constant pool entries requiredLong Immediate Subtraction. 6581 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLSub src2) %{ 6582 match(Set dst (SubL src1 src2)); 6583 ins_cost(ALU_COST); 6584 format %{ "addi $dst, $src1, -$src2\t#@subL_reg_imm" %} 6585 6586 ins_encode %{ 6587 // src2 is imm, so actually call the addi 6588 __ sub(as_Register($dst$$reg), 6589 as_Register($src1$$reg), 6590 $src2$$constant); 6591 %} 6592 6593 ins_pipe(ialu_reg_imm); 6594 %} 6595 6596 // Integer Negation (special case for sub) 6597 6598 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 6599 match(Set dst (SubI zero src)); 6600 ins_cost(ALU_COST); 6601 format %{ "subw $dst, x0, $src\t# int, #@negI_reg" %} 6602 6603 ins_encode %{ 6604 // actually call the subw 6605 __ negw(as_Register($dst$$reg), 6606 as_Register($src$$reg)); 6607 %} 6608 6609 ins_pipe(ialu_reg); 6610 %} 6611 6612 // Long Negation 6613 6614 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero) %{ 6615 match(Set dst (SubL zero src)); 6616 ins_cost(ALU_COST); 6617 format %{ "sub $dst, x0, $src\t# long, #@negL_reg" %} 6618 6619 ins_encode %{ 6620 // actually call the sub 6621 __ neg(as_Register($dst$$reg), 6622 as_Register($src$$reg)); 6623 %} 6624 6625 ins_pipe(ialu_reg); 6626 %} 6627 6628 // Integer Multiply 6629 6630 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6631 match(Set dst (MulI src1 src2)); 6632 ins_cost(IMUL_COST); 6633 format %{ "mulw $dst, $src1, $src2\t#@mulI" %} 6634 6635 //this means 2 word multi, and no sign extend to 64 bits 6636 ins_encode %{ 6637 // riscv64 mulw will sign-extension to high 32 bits in dst reg 6638 __ mulw(as_Register($dst$$reg), 6639 as_Register($src1$$reg), 6640 as_Register($src2$$reg)); 6641 %} 6642 6643 ins_pipe(imul_reg_reg); 6644 %} 6645 6646 // Long Multiply 6647 6648 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6649 match(Set dst (MulL src1 src2)); 6650 ins_cost(IMUL_COST); 6651 format %{ "mul $dst, $src1, $src2\t#@mulL" %} 6652 6653 ins_encode %{ 6654 __ mul(as_Register($dst$$reg), 6655 as_Register($src1$$reg), 6656 as_Register($src2$$reg)); 6657 %} 6658 6659 ins_pipe(lmul_reg_reg); 6660 %} 6661 6662 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) 6663 %{ 6664 match(Set dst (MulHiL src1 src2)); 6665 ins_cost(IMUL_COST); 6666 format %{ "mulh $dst, $src1, $src2\t# mulhi, #@mulHiL_rReg" %} 6667 6668 ins_encode %{ 6669 __ mulh(as_Register($dst$$reg), 6670 as_Register($src1$$reg), 6671 as_Register($src2$$reg)); 6672 %} 6673 6674 ins_pipe(lmul_reg_reg); 6675 %} 6676 6677 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2) 6678 %{ 6679 match(Set dst (UMulHiL src1 src2)); 6680 ins_cost(IMUL_COST); 6681 format %{ "mulhu $dst, $src1, $src2\t# umulhi, #@umulHiL_rReg" %} 6682 6683 ins_encode %{ 6684 __ mulhu(as_Register($dst$$reg), 6685 as_Register($src1$$reg), 6686 as_Register($src2$$reg)); 6687 %} 6688 6689 ins_pipe(lmul_reg_reg); 6690 %} 6691 6692 // Integer Divide 6693 6694 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6695 match(Set dst (DivI src1 src2)); 6696 ins_cost(IDIVSI_COST); 6697 format %{ "divw $dst, $src1, $src2\t#@divI"%} 6698 6699 ins_encode(riscv_enc_divw(dst, src1, src2)); 6700 ins_pipe(idiv_reg_reg); 6701 %} 6702 6703 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 6704 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 6705 ins_cost(ALU_COST); 6706 format %{ "srliw $dst, $src1, $div1\t# int signExtract, #@signExtract" %} 6707 6708 ins_encode %{ 6709 __ srliw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 6710 %} 6711 ins_pipe(ialu_reg_shift); 6712 %} 6713 6714 // Long Divide 6715 6716 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6717 match(Set dst (DivL src1 src2)); 6718 ins_cost(IDIVDI_COST); 6719 format %{ "div $dst, $src1, $src2\t#@divL" %} 6720 6721 ins_encode(riscv_enc_div(dst, src1, src2)); 6722 ins_pipe(ldiv_reg_reg); 6723 %} 6724 6725 instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{ 6726 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 6727 ins_cost(ALU_COST); 6728 format %{ "srli $dst, $src1, $div1\t# long signExtract, #@signExtractL" %} 6729 6730 ins_encode %{ 6731 __ srli(as_Register($dst$$reg), as_Register($src1$$reg), 63); 6732 %} 6733 ins_pipe(ialu_reg_shift); 6734 %} 6735 6736 // Integer Remainder 6737 6738 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6739 match(Set dst (ModI src1 src2)); 6740 ins_cost(IDIVSI_COST); 6741 format %{ "remw $dst, $src1, $src2\t#@modI" %} 6742 6743 ins_encode(riscv_enc_modw(dst, src1, src2)); 6744 ins_pipe(ialu_reg_reg); 6745 %} 6746 6747 // Long Remainder 6748 6749 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 6750 match(Set dst (ModL src1 src2)); 6751 ins_cost(IDIVDI_COST); 6752 format %{ "rem $dst, $src1, $src2\t#@modL" %} 6753 6754 ins_encode(riscv_enc_mod(dst, src1, src2)); 6755 ins_pipe(ialu_reg_reg); 6756 %} 6757 6758 // Integer Shifts 6759 6760 // Shift Left Register 6761 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6762 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6763 match(Set dst (LShiftI src1 src2)); 6764 ins_cost(ALU_COST); 6765 format %{ "sllw $dst, $src1, $src2\t#@lShiftI_reg_reg" %} 6766 6767 ins_encode %{ 6768 __ sllw(as_Register($dst$$reg), 6769 as_Register($src1$$reg), 6770 as_Register($src2$$reg)); 6771 %} 6772 6773 ins_pipe(ialu_reg_reg_vshift); 6774 %} 6775 6776 // Shift Left Immediate 6777 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6778 match(Set dst (LShiftI src1 src2)); 6779 ins_cost(ALU_COST); 6780 format %{ "slliw $dst, $src1, ($src2 & 0x1f)\t#@lShiftI_reg_imm" %} 6781 6782 ins_encode %{ 6783 // the shift amount is encoded in the lower 6784 // 5 bits of the I-immediate field for RV32I 6785 __ slliw(as_Register($dst$$reg), 6786 as_Register($src1$$reg), 6787 (unsigned) $src2$$constant & 0x1f); 6788 %} 6789 6790 ins_pipe(ialu_reg_shift); 6791 %} 6792 6793 // Shift Right Logical Register 6794 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6795 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6796 match(Set dst (URShiftI src1 src2)); 6797 ins_cost(ALU_COST); 6798 format %{ "srlw $dst, $src1, $src2\t#@urShiftI_reg_reg" %} 6799 6800 ins_encode %{ 6801 __ srlw(as_Register($dst$$reg), 6802 as_Register($src1$$reg), 6803 as_Register($src2$$reg)); 6804 %} 6805 6806 ins_pipe(ialu_reg_reg_vshift); 6807 %} 6808 6809 // Shift Right Logical Immediate 6810 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6811 match(Set dst (URShiftI src1 src2)); 6812 ins_cost(ALU_COST); 6813 format %{ "srliw $dst, $src1, ($src2 & 0x1f)\t#@urShiftI_reg_imm" %} 6814 6815 ins_encode %{ 6816 // the shift amount is encoded in the lower 6817 // 6 bits of the I-immediate field for RV64I 6818 __ srliw(as_Register($dst$$reg), 6819 as_Register($src1$$reg), 6820 (unsigned) $src2$$constant & 0x1f); 6821 %} 6822 6823 ins_pipe(ialu_reg_shift); 6824 %} 6825 6826 // Shift Right Arithmetic Register 6827 // In RV64I, only the low 5 bits of src2 are considered for the shift amount 6828 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 6829 match(Set dst (RShiftI src1 src2)); 6830 ins_cost(ALU_COST); 6831 format %{ "sraw $dst, $src1, $src2\t#@rShiftI_reg_reg" %} 6832 6833 ins_encode %{ 6834 // riscv will sign-ext dst high 32 bits 6835 __ sraw(as_Register($dst$$reg), 6836 as_Register($src1$$reg), 6837 as_Register($src2$$reg)); 6838 %} 6839 6840 ins_pipe(ialu_reg_reg_vshift); 6841 %} 6842 6843 // Shift Right Arithmetic Immediate 6844 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 6845 match(Set dst (RShiftI src1 src2)); 6846 ins_cost(ALU_COST); 6847 format %{ "sraiw $dst, $src1, ($src2 & 0x1f)\t#@rShiftI_reg_imm" %} 6848 6849 ins_encode %{ 6850 // riscv will sign-ext dst high 32 bits 6851 __ sraiw(as_Register($dst$$reg), 6852 as_Register($src1$$reg), 6853 (unsigned) $src2$$constant & 0x1f); 6854 %} 6855 6856 ins_pipe(ialu_reg_shift); 6857 %} 6858 6859 // Long Shifts 6860 6861 // Shift Left Register 6862 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 6863 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 6864 match(Set dst (LShiftL src1 src2)); 6865 6866 ins_cost(ALU_COST); 6867 format %{ "sll $dst, $src1, $src2\t#@lShiftL_reg_reg" %} 6868 6869 ins_encode %{ 6870 __ sll(as_Register($dst$$reg), 6871 as_Register($src1$$reg), 6872 as_Register($src2$$reg)); 6873 %} 6874 6875 ins_pipe(ialu_reg_reg_vshift); 6876 %} 6877 6878 // Shift Left Immediate 6879 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 6880 match(Set dst (LShiftL src1 src2)); 6881 6882 ins_cost(ALU_COST); 6883 format %{ "slli $dst, $src1, ($src2 & 0x3f)\t#@lShiftL_reg_imm" %} 6884 6885 ins_encode %{ 6886 // the shift amount is encoded in the lower 6887 // 6 bits of the I-immediate field for RV64I 6888 __ slli(as_Register($dst$$reg), 6889 as_Register($src1$$reg), 6890 (unsigned) $src2$$constant & 0x3f); 6891 %} 6892 6893 ins_pipe(ialu_reg_shift); 6894 %} 6895 6896 // Shift Right Logical Register 6897 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 6898 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 6899 match(Set dst (URShiftL src1 src2)); 6900 6901 ins_cost(ALU_COST); 6902 format %{ "srl $dst, $src1, $src2\t#@urShiftL_reg_reg" %} 6903 6904 ins_encode %{ 6905 __ srl(as_Register($dst$$reg), 6906 as_Register($src1$$reg), 6907 as_Register($src2$$reg)); 6908 %} 6909 6910 ins_pipe(ialu_reg_reg_vshift); 6911 %} 6912 6913 // Shift Right Logical Immediate 6914 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 6915 match(Set dst (URShiftL src1 src2)); 6916 6917 ins_cost(ALU_COST); 6918 format %{ "srli $dst, $src1, ($src2 & 0x3f)\t#@urShiftL_reg_imm" %} 6919 6920 ins_encode %{ 6921 // the shift amount is encoded in the lower 6922 // 6 bits of the I-immediate field for RV64I 6923 __ srli(as_Register($dst$$reg), 6924 as_Register($src1$$reg), 6925 (unsigned) $src2$$constant & 0x3f); 6926 %} 6927 6928 ins_pipe(ialu_reg_shift); 6929 %} 6930 6931 // A special-case pattern for card table stores. 6932 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 6933 match(Set dst (URShiftL (CastP2X src1) src2)); 6934 6935 ins_cost(ALU_COST); 6936 format %{ "srli $dst, p2x($src1), ($src2 & 0x3f)\t#@urShiftP_reg_imm" %} 6937 6938 ins_encode %{ 6939 // the shift amount is encoded in the lower 6940 // 6 bits of the I-immediate field for RV64I 6941 __ srli(as_Register($dst$$reg), 6942 as_Register($src1$$reg), 6943 (unsigned) $src2$$constant & 0x3f); 6944 %} 6945 6946 ins_pipe(ialu_reg_shift); 6947 %} 6948 6949 // Shift Right Arithmetic Register 6950 // In RV64I, only the low 6 bits of src2 are considered for the shift amount 6951 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 6952 match(Set dst (RShiftL src1 src2)); 6953 6954 ins_cost(ALU_COST); 6955 format %{ "sra $dst, $src1, $src2\t#@rShiftL_reg_reg" %} 6956 6957 ins_encode %{ 6958 __ sra(as_Register($dst$$reg), 6959 as_Register($src1$$reg), 6960 as_Register($src2$$reg)); 6961 %} 6962 6963 ins_pipe(ialu_reg_reg_vshift); 6964 %} 6965 6966 // Shift Right Arithmetic Immediate 6967 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 6968 match(Set dst (RShiftL src1 src2)); 6969 6970 ins_cost(ALU_COST); 6971 format %{ "srai $dst, $src1, ($src2 & 0x3f)\t#@rShiftL_reg_imm" %} 6972 6973 ins_encode %{ 6974 // the shift amount is encoded in the lower 6975 // 6 bits of the I-immediate field for RV64I 6976 __ srai(as_Register($dst$$reg), 6977 as_Register($src1$$reg), 6978 (unsigned) $src2$$constant & 0x3f); 6979 %} 6980 6981 ins_pipe(ialu_reg_shift); 6982 %} 6983 6984 instruct regI_not_reg(iRegINoSp dst, iRegI src1, immI_M1 m1) %{ 6985 match(Set dst (XorI src1 m1)); 6986 ins_cost(ALU_COST); 6987 format %{ "xori $dst, $src1, -1\t#@regI_not_reg" %} 6988 6989 ins_encode %{ 6990 __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); 6991 %} 6992 6993 ins_pipe(ialu_reg_imm); 6994 %} 6995 6996 instruct regL_not_reg(iRegLNoSp dst, iRegL src1, immL_M1 m1) %{ 6997 match(Set dst (XorL src1 m1)); 6998 ins_cost(ALU_COST); 6999 format %{ "xori $dst, $src1, -1\t#@regL_not_reg" %} 7000 7001 ins_encode %{ 7002 __ xori(as_Register($dst$$reg), as_Register($src1$$reg), -1); 7003 %} 7004 7005 ins_pipe(ialu_reg_imm); 7006 %} 7007 7008 7009 // ============================================================================ 7010 // Floating Point Arithmetic Instructions 7011 7012 instruct addF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7013 match(Set dst (AddF src1 src2)); 7014 7015 ins_cost(DEFAULT_COST * 5); 7016 format %{ "fadd.s $dst, $src1, $src2\t#@addF_reg_reg" %} 7017 7018 ins_encode %{ 7019 __ fadd_s(as_FloatRegister($dst$$reg), 7020 as_FloatRegister($src1$$reg), 7021 as_FloatRegister($src2$$reg)); 7022 %} 7023 7024 ins_pipe(fp_dop_reg_reg_s); 7025 %} 7026 7027 instruct addD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7028 match(Set dst (AddD src1 src2)); 7029 7030 ins_cost(DEFAULT_COST * 5); 7031 format %{ "fadd.d $dst, $src1, $src2\t#@addD_reg_reg" %} 7032 7033 ins_encode %{ 7034 __ fadd_d(as_FloatRegister($dst$$reg), 7035 as_FloatRegister($src1$$reg), 7036 as_FloatRegister($src2$$reg)); 7037 %} 7038 7039 ins_pipe(fp_dop_reg_reg_d); 7040 %} 7041 7042 instruct subF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7043 match(Set dst (SubF src1 src2)); 7044 7045 ins_cost(DEFAULT_COST * 5); 7046 format %{ "fsub.s $dst, $src1, $src2\t#@subF_reg_reg" %} 7047 7048 ins_encode %{ 7049 __ fsub_s(as_FloatRegister($dst$$reg), 7050 as_FloatRegister($src1$$reg), 7051 as_FloatRegister($src2$$reg)); 7052 %} 7053 7054 ins_pipe(fp_dop_reg_reg_s); 7055 %} 7056 7057 instruct subD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7058 match(Set dst (SubD src1 src2)); 7059 7060 ins_cost(DEFAULT_COST * 5); 7061 format %{ "fsub.d $dst, $src1, $src2\t#@subD_reg_reg" %} 7062 7063 ins_encode %{ 7064 __ fsub_d(as_FloatRegister($dst$$reg), 7065 as_FloatRegister($src1$$reg), 7066 as_FloatRegister($src2$$reg)); 7067 %} 7068 7069 ins_pipe(fp_dop_reg_reg_d); 7070 %} 7071 7072 instruct mulF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7073 match(Set dst (MulF src1 src2)); 7074 7075 ins_cost(FMUL_SINGLE_COST); 7076 format %{ "fmul.s $dst, $src1, $src2\t#@mulF_reg_reg" %} 7077 7078 ins_encode %{ 7079 __ fmul_s(as_FloatRegister($dst$$reg), 7080 as_FloatRegister($src1$$reg), 7081 as_FloatRegister($src2$$reg)); 7082 %} 7083 7084 ins_pipe(fp_dop_reg_reg_s); 7085 %} 7086 7087 instruct mulD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7088 match(Set dst (MulD src1 src2)); 7089 7090 ins_cost(FMUL_DOUBLE_COST); 7091 format %{ "fmul.d $dst, $src1, $src2\t#@mulD_reg_reg" %} 7092 7093 ins_encode %{ 7094 __ fmul_d(as_FloatRegister($dst$$reg), 7095 as_FloatRegister($src1$$reg), 7096 as_FloatRegister($src2$$reg)); 7097 %} 7098 7099 ins_pipe(fp_dop_reg_reg_d); 7100 %} 7101 7102 // src1 * src2 + src3 7103 instruct maddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7104 predicate(UseFMA); 7105 match(Set dst (FmaF src3 (Binary src1 src2))); 7106 7107 ins_cost(FMUL_SINGLE_COST); 7108 format %{ "fmadd.s $dst, $src1, $src2, $src3\t#@maddF_reg_reg" %} 7109 7110 ins_encode %{ 7111 __ fmadd_s(as_FloatRegister($dst$$reg), 7112 as_FloatRegister($src1$$reg), 7113 as_FloatRegister($src2$$reg), 7114 as_FloatRegister($src3$$reg)); 7115 %} 7116 7117 ins_pipe(pipe_class_default); 7118 %} 7119 7120 // src1 * src2 + src3 7121 instruct maddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7122 predicate(UseFMA); 7123 match(Set dst (FmaD src3 (Binary src1 src2))); 7124 7125 ins_cost(FMUL_DOUBLE_COST); 7126 format %{ "fmadd.d $dst, $src1, $src2, $src3\t#@maddD_reg_reg" %} 7127 7128 ins_encode %{ 7129 __ fmadd_d(as_FloatRegister($dst$$reg), 7130 as_FloatRegister($src1$$reg), 7131 as_FloatRegister($src2$$reg), 7132 as_FloatRegister($src3$$reg)); 7133 %} 7134 7135 ins_pipe(pipe_class_default); 7136 %} 7137 7138 // src1 * src2 - src3 7139 instruct msubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7140 predicate(UseFMA); 7141 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 7142 7143 ins_cost(FMUL_SINGLE_COST); 7144 format %{ "fmsub.s $dst, $src1, $src2, $src3\t#@msubF_reg_reg" %} 7145 7146 ins_encode %{ 7147 __ fmsub_s(as_FloatRegister($dst$$reg), 7148 as_FloatRegister($src1$$reg), 7149 as_FloatRegister($src2$$reg), 7150 as_FloatRegister($src3$$reg)); 7151 %} 7152 7153 ins_pipe(pipe_class_default); 7154 %} 7155 7156 // src1 * src2 - src3 7157 instruct msubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7158 predicate(UseFMA); 7159 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 7160 7161 ins_cost(FMUL_DOUBLE_COST); 7162 format %{ "fmsub.d $dst, $src1, $src2, $src3\t#@msubD_reg_reg" %} 7163 7164 ins_encode %{ 7165 __ fmsub_d(as_FloatRegister($dst$$reg), 7166 as_FloatRegister($src1$$reg), 7167 as_FloatRegister($src2$$reg), 7168 as_FloatRegister($src3$$reg)); 7169 %} 7170 7171 ins_pipe(pipe_class_default); 7172 %} 7173 7174 // -src1 * src2 + src3 7175 instruct nmsubF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7176 predicate(UseFMA); 7177 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 7178 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 7179 7180 ins_cost(FMUL_SINGLE_COST); 7181 format %{ "fnmsub.s $dst, $src1, $src2, $src3\t#@nmsubF_reg_reg" %} 7182 7183 ins_encode %{ 7184 __ fnmsub_s(as_FloatRegister($dst$$reg), 7185 as_FloatRegister($src1$$reg), 7186 as_FloatRegister($src2$$reg), 7187 as_FloatRegister($src3$$reg)); 7188 %} 7189 7190 ins_pipe(pipe_class_default); 7191 %} 7192 7193 // -src1 * src2 + src3 7194 instruct nmsubD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7195 predicate(UseFMA); 7196 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 7197 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 7198 7199 ins_cost(FMUL_DOUBLE_COST); 7200 format %{ "fnmsub.d $dst, $src1, $src2, $src3\t#@nmsubD_reg_reg" %} 7201 7202 ins_encode %{ 7203 __ fnmsub_d(as_FloatRegister($dst$$reg), 7204 as_FloatRegister($src1$$reg), 7205 as_FloatRegister($src2$$reg), 7206 as_FloatRegister($src3$$reg)); 7207 %} 7208 7209 ins_pipe(pipe_class_default); 7210 %} 7211 7212 // -src1 * src2 - src3 7213 instruct nmaddF_reg_reg(fRegF dst, fRegF src1, fRegF src2, fRegF src3) %{ 7214 predicate(UseFMA); 7215 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 7216 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 7217 7218 ins_cost(FMUL_SINGLE_COST); 7219 format %{ "fnmadd.s $dst, $src1, $src2, $src3\t#@nmaddF_reg_reg" %} 7220 7221 ins_encode %{ 7222 __ fnmadd_s(as_FloatRegister($dst$$reg), 7223 as_FloatRegister($src1$$reg), 7224 as_FloatRegister($src2$$reg), 7225 as_FloatRegister($src3$$reg)); 7226 %} 7227 7228 ins_pipe(pipe_class_default); 7229 %} 7230 7231 // -src1 * src2 - src3 7232 instruct nmaddD_reg_reg(fRegD dst, fRegD src1, fRegD src2, fRegD src3) %{ 7233 predicate(UseFMA); 7234 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 7235 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 7236 7237 ins_cost(FMUL_DOUBLE_COST); 7238 format %{ "fnmadd.d $dst, $src1, $src2, $src3\t#@nmaddD_reg_reg" %} 7239 7240 ins_encode %{ 7241 __ fnmadd_d(as_FloatRegister($dst$$reg), 7242 as_FloatRegister($src1$$reg), 7243 as_FloatRegister($src2$$reg), 7244 as_FloatRegister($src3$$reg)); 7245 %} 7246 7247 ins_pipe(pipe_class_default); 7248 %} 7249 7250 // Math.max(FF)F 7251 instruct maxF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ 7252 match(Set dst (MaxF src1 src2)); 7253 effect(TEMP_DEF dst, KILL cr); 7254 7255 format %{ "maxF $dst, $src1, $src2" %} 7256 7257 ins_encode %{ 7258 __ minmax_fp(as_FloatRegister($dst$$reg), 7259 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7260 false /* is_double */, false /* is_min */); 7261 %} 7262 7263 ins_pipe(pipe_class_default); 7264 %} 7265 7266 // Math.min(FF)F 7267 instruct minF_reg_reg(fRegF dst, fRegF src1, fRegF src2, rFlagsReg cr) %{ 7268 match(Set dst (MinF src1 src2)); 7269 effect(TEMP_DEF dst, KILL cr); 7270 7271 format %{ "minF $dst, $src1, $src2" %} 7272 7273 ins_encode %{ 7274 __ minmax_fp(as_FloatRegister($dst$$reg), 7275 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7276 false /* is_double */, true /* is_min */); 7277 %} 7278 7279 ins_pipe(pipe_class_default); 7280 %} 7281 7282 // Math.max(DD)D 7283 instruct maxD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ 7284 match(Set dst (MaxD src1 src2)); 7285 effect(TEMP_DEF dst, KILL cr); 7286 7287 format %{ "maxD $dst, $src1, $src2" %} 7288 7289 ins_encode %{ 7290 __ minmax_fp(as_FloatRegister($dst$$reg), 7291 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7292 true /* is_double */, false /* is_min */); 7293 %} 7294 7295 ins_pipe(pipe_class_default); 7296 %} 7297 7298 // Math.min(DD)D 7299 instruct minD_reg_reg(fRegD dst, fRegD src1, fRegD src2, rFlagsReg cr) %{ 7300 match(Set dst (MinD src1 src2)); 7301 effect(TEMP_DEF dst, KILL cr); 7302 7303 format %{ "minD $dst, $src1, $src2" %} 7304 7305 ins_encode %{ 7306 __ minmax_fp(as_FloatRegister($dst$$reg), 7307 as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), 7308 true /* is_double */, true /* is_min */); 7309 %} 7310 7311 ins_pipe(pipe_class_default); 7312 %} 7313 7314 // Float.isInfinite 7315 instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src) 7316 %{ 7317 match(Set dst (IsInfiniteF src)); 7318 7319 format %{ "isInfinite $dst, $src" %} 7320 ins_encode %{ 7321 __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7322 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0010000001); 7323 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7324 %} 7325 7326 ins_pipe(pipe_class_default); 7327 %} 7328 7329 // Double.isInfinite 7330 instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src) 7331 %{ 7332 match(Set dst (IsInfiniteD src)); 7333 7334 format %{ "isInfinite $dst, $src" %} 7335 ins_encode %{ 7336 __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7337 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0010000001); 7338 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7339 %} 7340 7341 ins_pipe(pipe_class_default); 7342 %} 7343 7344 // Float.isFinite 7345 instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src) 7346 %{ 7347 match(Set dst (IsFiniteF src)); 7348 7349 format %{ "isFinite $dst, $src" %} 7350 ins_encode %{ 7351 __ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7352 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0001111110); 7353 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7354 %} 7355 7356 ins_pipe(pipe_class_default); 7357 %} 7358 7359 // Double.isFinite 7360 instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src) 7361 %{ 7362 match(Set dst (IsFiniteD src)); 7363 7364 format %{ "isFinite $dst, $src" %} 7365 ins_encode %{ 7366 __ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 7367 __ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0001111110); 7368 __ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 7369 %} 7370 7371 ins_pipe(pipe_class_default); 7372 %} 7373 7374 instruct divF_reg_reg(fRegF dst, fRegF src1, fRegF src2) %{ 7375 match(Set dst (DivF src1 src2)); 7376 7377 ins_cost(FDIV_COST); 7378 format %{ "fdiv.s $dst, $src1, $src2\t#@divF_reg_reg" %} 7379 7380 ins_encode %{ 7381 __ fdiv_s(as_FloatRegister($dst$$reg), 7382 as_FloatRegister($src1$$reg), 7383 as_FloatRegister($src2$$reg)); 7384 %} 7385 7386 ins_pipe(fp_div_s); 7387 %} 7388 7389 instruct divD_reg_reg(fRegD dst, fRegD src1, fRegD src2) %{ 7390 match(Set dst (DivD src1 src2)); 7391 7392 ins_cost(FDIV_COST); 7393 format %{ "fdiv.d $dst, $src1, $src2\t#@divD_reg_reg" %} 7394 7395 ins_encode %{ 7396 __ fdiv_d(as_FloatRegister($dst$$reg), 7397 as_FloatRegister($src1$$reg), 7398 as_FloatRegister($src2$$reg)); 7399 %} 7400 7401 ins_pipe(fp_div_d); 7402 %} 7403 7404 instruct negF_reg_reg(fRegF dst, fRegF src) %{ 7405 match(Set dst (NegF src)); 7406 7407 ins_cost(XFER_COST); 7408 format %{ "fsgnjn.s $dst, $src, $src\t#@negF_reg_reg" %} 7409 7410 ins_encode %{ 7411 __ fneg_s(as_FloatRegister($dst$$reg), 7412 as_FloatRegister($src$$reg)); 7413 %} 7414 7415 ins_pipe(fp_uop_s); 7416 %} 7417 7418 instruct negD_reg_reg(fRegD dst, fRegD src) %{ 7419 match(Set dst (NegD src)); 7420 7421 ins_cost(XFER_COST); 7422 format %{ "fsgnjn.d $dst, $src, $src\t#@negD_reg_reg" %} 7423 7424 ins_encode %{ 7425 __ fneg_d(as_FloatRegister($dst$$reg), 7426 as_FloatRegister($src$$reg)); 7427 %} 7428 7429 ins_pipe(fp_uop_d); 7430 %} 7431 7432 instruct absI_reg(iRegINoSp dst, iRegIorL2I src) %{ 7433 match(Set dst (AbsI src)); 7434 7435 ins_cost(ALU_COST * 3); 7436 format %{ 7437 "sraiw t0, $src, 0x1f\n\t" 7438 "addw $dst, $src, t0\n\t" 7439 "xorr $dst, $dst, t0\t#@absI_reg" 7440 %} 7441 7442 ins_encode %{ 7443 __ sraiw(t0, as_Register($src$$reg), 0x1f); 7444 __ addw(as_Register($dst$$reg), as_Register($src$$reg), t0); 7445 __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); 7446 %} 7447 7448 ins_pipe(pipe_class_default); 7449 %} 7450 7451 instruct absL_reg(iRegLNoSp dst, iRegL src) %{ 7452 match(Set dst (AbsL src)); 7453 7454 ins_cost(ALU_COST * 3); 7455 format %{ 7456 "srai t0, $src, 0x3f\n\t" 7457 "add $dst, $src, t0\n\t" 7458 "xorr $dst, $dst, t0\t#@absL_reg" 7459 %} 7460 7461 ins_encode %{ 7462 __ srai(t0, as_Register($src$$reg), 0x3f); 7463 __ add(as_Register($dst$$reg), as_Register($src$$reg), t0); 7464 __ xorr(as_Register($dst$$reg), as_Register($dst$$reg), t0); 7465 %} 7466 7467 ins_pipe(pipe_class_default); 7468 %} 7469 7470 instruct absF_reg(fRegF dst, fRegF src) %{ 7471 match(Set dst (AbsF src)); 7472 7473 ins_cost(XFER_COST); 7474 format %{ "fsgnjx.s $dst, $src, $src\t#@absF_reg" %} 7475 ins_encode %{ 7476 __ fabs_s(as_FloatRegister($dst$$reg), 7477 as_FloatRegister($src$$reg)); 7478 %} 7479 7480 ins_pipe(fp_uop_s); 7481 %} 7482 7483 instruct absD_reg(fRegD dst, fRegD src) %{ 7484 match(Set dst (AbsD src)); 7485 7486 ins_cost(XFER_COST); 7487 format %{ "fsgnjx.d $dst, $src, $src\t#@absD_reg" %} 7488 ins_encode %{ 7489 __ fabs_d(as_FloatRegister($dst$$reg), 7490 as_FloatRegister($src$$reg)); 7491 %} 7492 7493 ins_pipe(fp_uop_d); 7494 %} 7495 7496 instruct sqrtF_reg(fRegF dst, fRegF src) %{ 7497 match(Set dst (SqrtF src)); 7498 7499 ins_cost(FSQRT_COST); 7500 format %{ "fsqrt.s $dst, $src\t#@sqrtF_reg" %} 7501 ins_encode %{ 7502 __ fsqrt_s(as_FloatRegister($dst$$reg), 7503 as_FloatRegister($src$$reg)); 7504 %} 7505 7506 ins_pipe(fp_sqrt_s); 7507 %} 7508 7509 instruct sqrtD_reg(fRegD dst, fRegD src) %{ 7510 match(Set dst (SqrtD src)); 7511 7512 ins_cost(FSQRT_COST); 7513 format %{ "fsqrt.d $dst, $src\t#@sqrtD_reg" %} 7514 ins_encode %{ 7515 __ fsqrt_d(as_FloatRegister($dst$$reg), 7516 as_FloatRegister($src$$reg)); 7517 %} 7518 7519 ins_pipe(fp_sqrt_d); 7520 %} 7521 7522 // Arithmetic Instructions End 7523 7524 // ============================================================================ 7525 // Logical Instructions 7526 7527 // Register And 7528 instruct andI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7529 match(Set dst (AndI src1 src2)); 7530 7531 format %{ "andr $dst, $src1, $src2\t#@andI_reg_reg" %} 7532 7533 ins_cost(ALU_COST); 7534 ins_encode %{ 7535 __ andr(as_Register($dst$$reg), 7536 as_Register($src1$$reg), 7537 as_Register($src2$$reg)); 7538 %} 7539 7540 ins_pipe(ialu_reg_reg); 7541 %} 7542 7543 // Immediate And 7544 instruct andI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7545 match(Set dst (AndI src1 src2)); 7546 7547 format %{ "andi $dst, $src1, $src2\t#@andI_reg_imm" %} 7548 7549 ins_cost(ALU_COST); 7550 ins_encode %{ 7551 __ andi(as_Register($dst$$reg), 7552 as_Register($src1$$reg), 7553 (int32_t)($src2$$constant)); 7554 %} 7555 7556 ins_pipe(ialu_reg_imm); 7557 %} 7558 7559 // Register Or 7560 instruct orI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7561 match(Set dst (OrI src1 src2)); 7562 7563 format %{ "orr $dst, $src1, $src2\t#@orI_reg_reg" %} 7564 7565 ins_cost(ALU_COST); 7566 ins_encode %{ 7567 __ orr(as_Register($dst$$reg), 7568 as_Register($src1$$reg), 7569 as_Register($src2$$reg)); 7570 %} 7571 7572 ins_pipe(ialu_reg_reg); 7573 %} 7574 7575 // Immediate Or 7576 instruct orI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7577 match(Set dst (OrI src1 src2)); 7578 7579 format %{ "ori $dst, $src1, $src2\t#@orI_reg_imm" %} 7580 7581 ins_cost(ALU_COST); 7582 ins_encode %{ 7583 __ ori(as_Register($dst$$reg), 7584 as_Register($src1$$reg), 7585 (int32_t)($src2$$constant)); 7586 %} 7587 7588 ins_pipe(ialu_reg_imm); 7589 %} 7590 7591 // Register Xor 7592 instruct xorI_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2) %{ 7593 match(Set dst (XorI src1 src2)); 7594 7595 format %{ "xorr $dst, $src1, $src2\t#@xorI_reg_reg" %} 7596 7597 ins_cost(ALU_COST); 7598 ins_encode %{ 7599 __ xorr(as_Register($dst$$reg), 7600 as_Register($src1$$reg), 7601 as_Register($src2$$reg)); 7602 %} 7603 7604 ins_pipe(ialu_reg_reg); 7605 %} 7606 7607 // Immediate Xor 7608 instruct xorI_reg_imm(iRegINoSp dst, iRegI src1, immIAdd src2) %{ 7609 match(Set dst (XorI src1 src2)); 7610 7611 format %{ "xori $dst, $src1, $src2\t#@xorI_reg_imm" %} 7612 7613 ins_cost(ALU_COST); 7614 ins_encode %{ 7615 __ xori(as_Register($dst$$reg), 7616 as_Register($src1$$reg), 7617 (int32_t)($src2$$constant)); 7618 %} 7619 7620 ins_pipe(ialu_reg_imm); 7621 %} 7622 7623 // Register And Long 7624 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7625 match(Set dst (AndL src1 src2)); 7626 7627 format %{ "andr $dst, $src1, $src2\t#@andL_reg_reg" %} 7628 7629 ins_cost(ALU_COST); 7630 ins_encode %{ 7631 __ andr(as_Register($dst$$reg), 7632 as_Register($src1$$reg), 7633 as_Register($src2$$reg)); 7634 %} 7635 7636 ins_pipe(ialu_reg_reg); 7637 %} 7638 7639 // Immediate And Long 7640 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7641 match(Set dst (AndL src1 src2)); 7642 7643 format %{ "andi $dst, $src1, $src2\t#@andL_reg_imm" %} 7644 7645 ins_cost(ALU_COST); 7646 ins_encode %{ 7647 __ andi(as_Register($dst$$reg), 7648 as_Register($src1$$reg), 7649 (int32_t)($src2$$constant)); 7650 %} 7651 7652 ins_pipe(ialu_reg_imm); 7653 %} 7654 7655 // Register Or Long 7656 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7657 match(Set dst (OrL src1 src2)); 7658 7659 format %{ "orr $dst, $src1, $src2\t#@orL_reg_reg" %} 7660 7661 ins_cost(ALU_COST); 7662 ins_encode %{ 7663 __ orr(as_Register($dst$$reg), 7664 as_Register($src1$$reg), 7665 as_Register($src2$$reg)); 7666 %} 7667 7668 ins_pipe(ialu_reg_reg); 7669 %} 7670 7671 // Immediate Or Long 7672 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7673 match(Set dst (OrL src1 src2)); 7674 7675 format %{ "ori $dst, $src1, $src2\t#@orL_reg_imm" %} 7676 7677 ins_cost(ALU_COST); 7678 ins_encode %{ 7679 __ ori(as_Register($dst$$reg), 7680 as_Register($src1$$reg), 7681 (int32_t)($src2$$constant)); 7682 %} 7683 7684 ins_pipe(ialu_reg_imm); 7685 %} 7686 7687 // Register Xor Long 7688 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7689 match(Set dst (XorL src1 src2)); 7690 7691 format %{ "xorr $dst, $src1, $src2\t#@xorL_reg_reg" %} 7692 7693 ins_cost(ALU_COST); 7694 ins_encode %{ 7695 __ xorr(as_Register($dst$$reg), 7696 as_Register($src1$$reg), 7697 as_Register($src2$$reg)); 7698 %} 7699 7700 ins_pipe(ialu_reg_reg); 7701 %} 7702 7703 // Immediate Xor Long 7704 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLAdd src2) %{ 7705 match(Set dst (XorL src1 src2)); 7706 7707 ins_cost(ALU_COST); 7708 format %{ "xori $dst, $src1, $src2\t#@xorL_reg_imm" %} 7709 7710 ins_encode %{ 7711 __ xori(as_Register($dst$$reg), 7712 as_Register($src1$$reg), 7713 (int32_t)($src2$$constant)); 7714 %} 7715 7716 ins_pipe(ialu_reg_imm); 7717 %} 7718 7719 // ============================================================================ 7720 // BSWAP Instructions 7721 7722 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) %{ 7723 match(Set dst (ReverseBytesI src)); 7724 effect(KILL cr); 7725 7726 ins_cost(ALU_COST * 13); 7727 format %{ "revb_w_w $dst, $src\t#@bytes_reverse_int" %} 7728 7729 ins_encode %{ 7730 __ revb_w_w(as_Register($dst$$reg), as_Register($src$$reg)); 7731 %} 7732 7733 ins_pipe(pipe_class_default); 7734 %} 7735 7736 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src, rFlagsReg cr) %{ 7737 match(Set dst (ReverseBytesL src)); 7738 effect(KILL cr); 7739 7740 ins_cost(ALU_COST * 29); 7741 format %{ "revb $dst, $src\t#@bytes_reverse_long" %} 7742 7743 ins_encode %{ 7744 __ revb(as_Register($dst$$reg), as_Register($src$$reg)); 7745 %} 7746 7747 ins_pipe(pipe_class_default); 7748 %} 7749 7750 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7751 match(Set dst (ReverseBytesUS src)); 7752 7753 ins_cost(ALU_COST * 5); 7754 format %{ "revb_h_h_u $dst, $src\t#@bytes_reverse_unsigned_short" %} 7755 7756 ins_encode %{ 7757 __ revb_h_h_u(as_Register($dst$$reg), as_Register($src$$reg)); 7758 %} 7759 7760 ins_pipe(pipe_class_default); 7761 %} 7762 7763 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7764 match(Set dst (ReverseBytesS src)); 7765 7766 ins_cost(ALU_COST * 5); 7767 format %{ "revb_h_h $dst, $src\t#@bytes_reverse_short" %} 7768 7769 ins_encode %{ 7770 __ revb_h_h(as_Register($dst$$reg), as_Register($src$$reg)); 7771 %} 7772 7773 ins_pipe(pipe_class_default); 7774 %} 7775 7776 // ============================================================================ 7777 // MemBar Instruction 7778 7779 instruct load_fence() %{ 7780 match(LoadFence); 7781 ins_cost(ALU_COST); 7782 7783 format %{ "#@load_fence" %} 7784 7785 ins_encode %{ 7786 __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); 7787 %} 7788 ins_pipe(pipe_serial); 7789 %} 7790 7791 instruct membar_acquire() %{ 7792 match(MemBarAcquire); 7793 ins_cost(ALU_COST); 7794 7795 format %{ "#@membar_acquire\n\t" 7796 "fence ir iorw" %} 7797 7798 ins_encode %{ 7799 __ block_comment("membar_acquire"); 7800 __ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore); 7801 %} 7802 7803 ins_pipe(pipe_serial); 7804 %} 7805 7806 instruct membar_acquire_lock() %{ 7807 match(MemBarAcquireLock); 7808 ins_cost(0); 7809 7810 format %{ "#@membar_acquire_lock (elided)" %} 7811 7812 ins_encode %{ 7813 __ block_comment("membar_acquire_lock (elided)"); 7814 %} 7815 7816 ins_pipe(pipe_serial); 7817 %} 7818 7819 instruct store_fence() %{ 7820 match(StoreFence); 7821 ins_cost(ALU_COST); 7822 7823 format %{ "#@store_fence" %} 7824 7825 ins_encode %{ 7826 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 7827 %} 7828 ins_pipe(pipe_serial); 7829 %} 7830 7831 instruct membar_release() %{ 7832 match(MemBarRelease); 7833 ins_cost(ALU_COST); 7834 7835 format %{ "#@membar_release\n\t" 7836 "fence iorw ow" %} 7837 7838 ins_encode %{ 7839 __ block_comment("membar_release"); 7840 __ membar(MacroAssembler::LoadStore | MacroAssembler::StoreStore); 7841 %} 7842 ins_pipe(pipe_serial); 7843 %} 7844 7845 instruct membar_storestore() %{ 7846 match(MemBarStoreStore); 7847 match(StoreStoreFence); 7848 ins_cost(ALU_COST); 7849 7850 format %{ "MEMBAR-store-store\t#@membar_storestore" %} 7851 7852 ins_encode %{ 7853 __ membar(MacroAssembler::StoreStore); 7854 %} 7855 ins_pipe(pipe_serial); 7856 %} 7857 7858 instruct membar_release_lock() %{ 7859 match(MemBarReleaseLock); 7860 ins_cost(0); 7861 7862 format %{ "#@membar_release_lock (elided)" %} 7863 7864 ins_encode %{ 7865 __ block_comment("membar_release_lock (elided)"); 7866 %} 7867 7868 ins_pipe(pipe_serial); 7869 %} 7870 7871 instruct membar_volatile() %{ 7872 match(MemBarVolatile); 7873 ins_cost(ALU_COST); 7874 7875 format %{ "#@membar_volatile\n\t" 7876 "fence iorw iorw"%} 7877 7878 ins_encode %{ 7879 __ block_comment("membar_volatile"); 7880 __ membar(MacroAssembler::StoreLoad); 7881 %} 7882 7883 ins_pipe(pipe_serial); 7884 %} 7885 7886 instruct spin_wait() %{ 7887 predicate(UseZihintpause); 7888 match(OnSpinWait); 7889 ins_cost(CACHE_MISS_COST); 7890 7891 format %{ "spin_wait" %} 7892 7893 ins_encode %{ 7894 __ pause(); 7895 %} 7896 7897 ins_pipe(pipe_serial); 7898 %} 7899 7900 // ============================================================================ 7901 // Cast Instructions (Java-level type cast) 7902 7903 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7904 match(Set dst (CastX2P src)); 7905 7906 ins_cost(ALU_COST); 7907 format %{ "mv $dst, $src\t# long -> ptr, #@castX2P" %} 7908 7909 ins_encode %{ 7910 if ($dst$$reg != $src$$reg) { 7911 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 7912 } 7913 %} 7914 7915 ins_pipe(ialu_reg); 7916 %} 7917 7918 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7919 match(Set dst (CastP2X src)); 7920 7921 ins_cost(ALU_COST); 7922 format %{ "mv $dst, $src\t# ptr -> long, #@castP2X" %} 7923 7924 ins_encode %{ 7925 if ($dst$$reg != $src$$reg) { 7926 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 7927 } 7928 %} 7929 7930 ins_pipe(ialu_reg); 7931 %} 7932 7933 instruct castPP(iRegPNoSp dst) 7934 %{ 7935 match(Set dst (CastPP dst)); 7936 ins_cost(0); 7937 7938 size(0); 7939 format %{ "# castPP of $dst, #@castPP" %} 7940 ins_encode(/* empty encoding */); 7941 ins_pipe(pipe_class_empty); 7942 %} 7943 7944 instruct castLL(iRegL dst) 7945 %{ 7946 match(Set dst (CastLL dst)); 7947 7948 size(0); 7949 format %{ "# castLL of $dst, #@castLL" %} 7950 ins_encode(/* empty encoding */); 7951 ins_cost(0); 7952 ins_pipe(pipe_class_empty); 7953 %} 7954 7955 instruct castII(iRegI dst) 7956 %{ 7957 match(Set dst (CastII dst)); 7958 7959 size(0); 7960 format %{ "# castII of $dst, #@castII" %} 7961 ins_encode(/* empty encoding */); 7962 ins_cost(0); 7963 ins_pipe(pipe_class_empty); 7964 %} 7965 7966 instruct checkCastPP(iRegPNoSp dst) 7967 %{ 7968 match(Set dst (CheckCastPP dst)); 7969 7970 size(0); 7971 ins_cost(0); 7972 format %{ "# checkcastPP of $dst, #@checkCastPP" %} 7973 ins_encode(/* empty encoding */); 7974 ins_pipe(pipe_class_empty); 7975 %} 7976 7977 instruct castFF(fRegF dst) 7978 %{ 7979 match(Set dst (CastFF dst)); 7980 7981 size(0); 7982 format %{ "# castFF of $dst" %} 7983 ins_encode(/* empty encoding */); 7984 ins_cost(0); 7985 ins_pipe(pipe_class_empty); 7986 %} 7987 7988 instruct castDD(fRegD dst) 7989 %{ 7990 match(Set dst (CastDD dst)); 7991 7992 size(0); 7993 format %{ "# castDD of $dst" %} 7994 ins_encode(/* empty encoding */); 7995 ins_cost(0); 7996 ins_pipe(pipe_class_empty); 7997 %} 7998 7999 instruct castVV(vReg dst) 8000 %{ 8001 match(Set dst (CastVV dst)); 8002 8003 size(0); 8004 format %{ "# castVV of $dst" %} 8005 ins_encode(/* empty encoding */); 8006 ins_cost(0); 8007 ins_pipe(pipe_class_empty); 8008 %} 8009 8010 // ============================================================================ 8011 // Convert Instructions 8012 8013 // int to bool 8014 instruct convI2Bool(iRegINoSp dst, iRegI src) 8015 %{ 8016 match(Set dst (Conv2B src)); 8017 8018 ins_cost(ALU_COST); 8019 format %{ "snez $dst, $src\t#@convI2Bool" %} 8020 8021 ins_encode %{ 8022 __ snez(as_Register($dst$$reg), as_Register($src$$reg)); 8023 %} 8024 8025 ins_pipe(ialu_reg); 8026 %} 8027 8028 // pointer to bool 8029 instruct convP2Bool(iRegINoSp dst, iRegP src) 8030 %{ 8031 match(Set dst (Conv2B src)); 8032 8033 ins_cost(ALU_COST); 8034 format %{ "snez $dst, $src\t#@convP2Bool" %} 8035 8036 ins_encode %{ 8037 __ snez(as_Register($dst$$reg), as_Register($src$$reg)); 8038 %} 8039 8040 ins_pipe(ialu_reg); 8041 %} 8042 8043 // int <-> long 8044 8045 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 8046 %{ 8047 match(Set dst (ConvI2L src)); 8048 8049 ins_cost(ALU_COST); 8050 format %{ "addw $dst, $src, zr\t#@convI2L_reg_reg" %} 8051 ins_encode %{ 8052 __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8053 %} 8054 ins_pipe(ialu_reg); 8055 %} 8056 8057 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 8058 match(Set dst (ConvL2I src)); 8059 8060 ins_cost(ALU_COST); 8061 format %{ "addw $dst, $src, zr\t#@convL2I_reg" %} 8062 8063 ins_encode %{ 8064 __ sign_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8065 %} 8066 8067 ins_pipe(ialu_reg); 8068 %} 8069 8070 // int to unsigned long (Zero-extend) 8071 instruct convI2UL_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 8072 %{ 8073 match(Set dst (AndL (ConvI2L src) mask)); 8074 8075 ins_cost(ALU_COST * 2); 8076 format %{ "zero_extend $dst, $src, 32\t# i2ul, #@convI2UL_reg_reg" %} 8077 8078 ins_encode %{ 8079 __ zero_extend(as_Register($dst$$reg), as_Register($src$$reg), 32); 8080 %} 8081 8082 ins_pipe(ialu_reg_shift); 8083 %} 8084 8085 // float <-> double 8086 8087 instruct convF2D_reg(fRegD dst, fRegF src) %{ 8088 match(Set dst (ConvF2D src)); 8089 8090 ins_cost(XFER_COST); 8091 format %{ "fcvt.d.s $dst, $src\t#@convF2D_reg" %} 8092 8093 ins_encode %{ 8094 __ fcvt_d_s(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 8095 %} 8096 8097 ins_pipe(fp_f2d); 8098 %} 8099 8100 instruct convD2F_reg(fRegF dst, fRegD src) %{ 8101 match(Set dst (ConvD2F src)); 8102 8103 ins_cost(XFER_COST); 8104 format %{ "fcvt.s.d $dst, $src\t#@convD2F_reg" %} 8105 8106 ins_encode %{ 8107 __ fcvt_s_d(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 8108 %} 8109 8110 ins_pipe(fp_d2f); 8111 %} 8112 8113 // float <-> int 8114 8115 instruct convF2I_reg_reg(iRegINoSp dst, fRegF src) %{ 8116 match(Set dst (ConvF2I src)); 8117 8118 ins_cost(XFER_COST); 8119 format %{ "fcvt.w.s $dst, $src\t#@convF2I_reg_reg" %} 8120 8121 ins_encode %{ 8122 __ fcvt_w_s_safe($dst$$Register, $src$$FloatRegister); 8123 %} 8124 8125 ins_pipe(fp_f2i); 8126 %} 8127 8128 instruct convI2F_reg_reg(fRegF dst, iRegIorL2I src) %{ 8129 match(Set dst (ConvI2F src)); 8130 8131 ins_cost(XFER_COST); 8132 format %{ "fcvt.s.w $dst, $src\t#@convI2F_reg_reg" %} 8133 8134 ins_encode %{ 8135 __ fcvt_s_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8136 %} 8137 8138 ins_pipe(fp_i2f); 8139 %} 8140 8141 // float <-> long 8142 8143 instruct convF2L_reg_reg(iRegLNoSp dst, fRegF src) %{ 8144 match(Set dst (ConvF2L src)); 8145 8146 ins_cost(XFER_COST); 8147 format %{ "fcvt.l.s $dst, $src\t#@convF2L_reg_reg" %} 8148 8149 ins_encode %{ 8150 __ fcvt_l_s_safe($dst$$Register, $src$$FloatRegister); 8151 %} 8152 8153 ins_pipe(fp_f2l); 8154 %} 8155 8156 instruct convL2F_reg_reg(fRegF dst, iRegL src) %{ 8157 match(Set dst (ConvL2F src)); 8158 8159 ins_cost(XFER_COST); 8160 format %{ "fcvt.s.l $dst, $src\t#@convL2F_reg_reg" %} 8161 8162 ins_encode %{ 8163 __ fcvt_s_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8164 %} 8165 8166 ins_pipe(fp_l2f); 8167 %} 8168 8169 // double <-> int 8170 8171 instruct convD2I_reg_reg(iRegINoSp dst, fRegD src) %{ 8172 match(Set dst (ConvD2I src)); 8173 8174 ins_cost(XFER_COST); 8175 format %{ "fcvt.w.d $dst, $src\t#@convD2I_reg_reg" %} 8176 8177 ins_encode %{ 8178 __ fcvt_w_d_safe($dst$$Register, $src$$FloatRegister); 8179 %} 8180 8181 ins_pipe(fp_d2i); 8182 %} 8183 8184 instruct convI2D_reg_reg(fRegD dst, iRegIorL2I src) %{ 8185 match(Set dst (ConvI2D src)); 8186 8187 ins_cost(XFER_COST); 8188 format %{ "fcvt.d.w $dst, $src\t#@convI2D_reg_reg" %} 8189 8190 ins_encode %{ 8191 __ fcvt_d_w(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8192 %} 8193 8194 ins_pipe(fp_i2d); 8195 %} 8196 8197 // double <-> long 8198 8199 instruct convD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ 8200 match(Set dst (ConvD2L src)); 8201 8202 ins_cost(XFER_COST); 8203 format %{ "fcvt.l.d $dst, $src\t#@convD2L_reg_reg" %} 8204 8205 ins_encode %{ 8206 __ fcvt_l_d_safe($dst$$Register, $src$$FloatRegister); 8207 %} 8208 8209 ins_pipe(fp_d2l); 8210 %} 8211 8212 instruct convL2D_reg_reg(fRegD dst, iRegL src) %{ 8213 match(Set dst (ConvL2D src)); 8214 8215 ins_cost(XFER_COST); 8216 format %{ "fcvt.d.l $dst, $src\t#@convL2D_reg_reg" %} 8217 8218 ins_encode %{ 8219 __ fcvt_d_l(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8220 %} 8221 8222 ins_pipe(fp_l2d); 8223 %} 8224 8225 // Convert oop into int for vectors alignment masking 8226 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8227 match(Set dst (ConvL2I (CastP2X src))); 8228 8229 ins_cost(ALU_COST * 2); 8230 format %{ "zero_extend $dst, $src, 32\t# ptr -> int, #@convP2I" %} 8231 8232 ins_encode %{ 8233 __ zero_extend($dst$$Register, $src$$Register, 32); 8234 %} 8235 8236 ins_pipe(ialu_reg); 8237 %} 8238 8239 // Convert compressed oop into int for vectors alignment masking 8240 // in case of 32bit oops (heap < 4Gb). 8241 instruct convN2I(iRegINoSp dst, iRegN src) 8242 %{ 8243 predicate(CompressedOops::shift() == 0); 8244 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8245 8246 ins_cost(ALU_COST); 8247 format %{ "mv $dst, $src\t# compressed ptr -> int, #@convN2I" %} 8248 8249 ins_encode %{ 8250 __ mv($dst$$Register, $src$$Register); 8251 %} 8252 8253 ins_pipe(ialu_reg); 8254 %} 8255 8256 instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{ 8257 match(Set dst (RoundD src)); 8258 8259 ins_cost(XFER_COST + BRANCH_COST); 8260 effect(TEMP ftmp); 8261 format %{ "java_round_double $dst, $src\t#@round_double_reg" %} 8262 8263 ins_encode %{ 8264 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg)); 8265 %} 8266 8267 ins_pipe(pipe_slow); 8268 %} 8269 8270 instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{ 8271 match(Set dst (RoundF src)); 8272 8273 ins_cost(XFER_COST + BRANCH_COST); 8274 effect(TEMP ftmp); 8275 format %{ "java_round_float $dst, $src\t#@round_float_reg" %} 8276 8277 ins_encode %{ 8278 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg)); 8279 %} 8280 8281 ins_pipe(pipe_slow); 8282 %} 8283 8284 // Convert oop pointer into compressed form 8285 instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{ 8286 match(Set dst (EncodeP src)); 8287 ins_cost(ALU_COST); 8288 format %{ "encode_heap_oop $dst, $src\t#@encodeHeapOop" %} 8289 ins_encode %{ 8290 Register s = $src$$Register; 8291 Register d = $dst$$Register; 8292 __ encode_heap_oop(d, s); 8293 %} 8294 ins_pipe(pipe_class_default); 8295 %} 8296 8297 instruct decodeHeapOop(iRegPNoSp dst, iRegN src) %{ 8298 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8299 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8300 match(Set dst (DecodeN src)); 8301 8302 ins_cost(0); 8303 format %{ "decode_heap_oop $dst, $src\t#@decodeHeapOop" %} 8304 ins_encode %{ 8305 Register s = $src$$Register; 8306 Register d = $dst$$Register; 8307 __ decode_heap_oop(d, s); 8308 %} 8309 ins_pipe(pipe_class_default); 8310 %} 8311 8312 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src) %{ 8313 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8314 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8315 match(Set dst (DecodeN src)); 8316 8317 ins_cost(0); 8318 format %{ "decode_heap_oop_not_null $dst, $src\t#@decodeHeapOop_not_null" %} 8319 ins_encode %{ 8320 Register s = $src$$Register; 8321 Register d = $dst$$Register; 8322 __ decode_heap_oop_not_null(d, s); 8323 %} 8324 ins_pipe(pipe_class_default); 8325 %} 8326 8327 // Convert klass pointer into compressed form. 8328 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8329 match(Set dst (EncodePKlass src)); 8330 8331 ins_cost(ALU_COST); 8332 format %{ "encode_klass_not_null $dst, $src\t#@encodeKlass_not_null" %} 8333 8334 ins_encode %{ 8335 Register src_reg = as_Register($src$$reg); 8336 Register dst_reg = as_Register($dst$$reg); 8337 __ encode_klass_not_null(dst_reg, src_reg, t0); 8338 %} 8339 8340 ins_pipe(pipe_class_default); 8341 %} 8342 8343 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src, iRegPNoSp tmp) %{ 8344 match(Set dst (DecodeNKlass src)); 8345 8346 effect(TEMP tmp); 8347 8348 ins_cost(ALU_COST); 8349 format %{ "decode_klass_not_null $dst, $src\t#@decodeKlass_not_null" %} 8350 8351 ins_encode %{ 8352 Register src_reg = as_Register($src$$reg); 8353 Register dst_reg = as_Register($dst$$reg); 8354 Register tmp_reg = as_Register($tmp$$reg); 8355 __ decode_klass_not_null(dst_reg, src_reg, tmp_reg); 8356 %} 8357 8358 ins_pipe(pipe_class_default); 8359 %} 8360 8361 // stack <-> reg and reg <-> reg shuffles with no conversion 8362 8363 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 8364 8365 match(Set dst (MoveF2I src)); 8366 8367 effect(DEF dst, USE src); 8368 8369 ins_cost(LOAD_COST); 8370 8371 format %{ "lw $dst, $src\t#@MoveF2I_stack_reg" %} 8372 8373 ins_encode %{ 8374 __ lw(as_Register($dst$$reg), Address(sp, $src$$disp)); 8375 %} 8376 8377 ins_pipe(iload_reg_reg); 8378 8379 %} 8380 8381 instruct MoveI2F_stack_reg(fRegF dst, stackSlotI src) %{ 8382 8383 match(Set dst (MoveI2F src)); 8384 8385 effect(DEF dst, USE src); 8386 8387 ins_cost(LOAD_COST); 8388 8389 format %{ "flw $dst, $src\t#@MoveI2F_stack_reg" %} 8390 8391 ins_encode %{ 8392 __ flw(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 8393 %} 8394 8395 ins_pipe(fp_load_mem_s); 8396 8397 %} 8398 8399 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 8400 8401 match(Set dst (MoveD2L src)); 8402 8403 effect(DEF dst, USE src); 8404 8405 ins_cost(LOAD_COST); 8406 8407 format %{ "ld $dst, $src\t#@MoveD2L_stack_reg" %} 8408 8409 ins_encode %{ 8410 __ ld(as_Register($dst$$reg), Address(sp, $src$$disp)); 8411 %} 8412 8413 ins_pipe(iload_reg_reg); 8414 8415 %} 8416 8417 instruct MoveL2D_stack_reg(fRegD dst, stackSlotL src) %{ 8418 8419 match(Set dst (MoveL2D src)); 8420 8421 effect(DEF dst, USE src); 8422 8423 ins_cost(LOAD_COST); 8424 8425 format %{ "fld $dst, $src\t#@MoveL2D_stack_reg" %} 8426 8427 ins_encode %{ 8428 __ fld(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 8429 %} 8430 8431 ins_pipe(fp_load_mem_d); 8432 8433 %} 8434 8435 instruct MoveF2I_reg_stack(stackSlotI dst, fRegF src) %{ 8436 8437 match(Set dst (MoveF2I src)); 8438 8439 effect(DEF dst, USE src); 8440 8441 ins_cost(STORE_COST); 8442 8443 format %{ "fsw $src, $dst\t#@MoveF2I_reg_stack" %} 8444 8445 ins_encode %{ 8446 __ fsw(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 8447 %} 8448 8449 ins_pipe(fp_store_reg_s); 8450 8451 %} 8452 8453 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 8454 8455 match(Set dst (MoveI2F src)); 8456 8457 effect(DEF dst, USE src); 8458 8459 ins_cost(STORE_COST); 8460 8461 format %{ "sw $src, $dst\t#@MoveI2F_reg_stack" %} 8462 8463 ins_encode %{ 8464 __ sw(as_Register($src$$reg), Address(sp, $dst$$disp)); 8465 %} 8466 8467 ins_pipe(istore_reg_reg); 8468 8469 %} 8470 8471 instruct MoveD2L_reg_stack(stackSlotL dst, fRegD src) %{ 8472 8473 match(Set dst (MoveD2L src)); 8474 8475 effect(DEF dst, USE src); 8476 8477 ins_cost(STORE_COST); 8478 8479 format %{ "fsd $dst, $src\t#@MoveD2L_reg_stack" %} 8480 8481 ins_encode %{ 8482 __ fsd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 8483 %} 8484 8485 ins_pipe(fp_store_reg_d); 8486 8487 %} 8488 8489 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 8490 8491 match(Set dst (MoveL2D src)); 8492 8493 effect(DEF dst, USE src); 8494 8495 ins_cost(STORE_COST); 8496 8497 format %{ "sd $src, $dst\t#@MoveL2D_reg_stack" %} 8498 8499 ins_encode %{ 8500 __ sd(as_Register($src$$reg), Address(sp, $dst$$disp)); 8501 %} 8502 8503 ins_pipe(istore_reg_reg); 8504 8505 %} 8506 8507 instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{ 8508 8509 match(Set dst (MoveF2I src)); 8510 8511 effect(DEF dst, USE src); 8512 8513 ins_cost(FMVX_COST); 8514 8515 format %{ "fmv.x.w $dst, $src\t#@MoveL2D_reg_stack" %} 8516 8517 ins_encode %{ 8518 __ fmv_x_w(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 8519 %} 8520 8521 ins_pipe(fp_f2i); 8522 8523 %} 8524 8525 instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{ 8526 8527 match(Set dst (MoveI2F src)); 8528 8529 effect(DEF dst, USE src); 8530 8531 ins_cost(FMVX_COST); 8532 8533 format %{ "fmv.w.x $dst, $src\t#@MoveI2F_reg_reg" %} 8534 8535 ins_encode %{ 8536 __ fmv_w_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8537 %} 8538 8539 ins_pipe(fp_i2f); 8540 8541 %} 8542 8543 instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{ 8544 8545 match(Set dst (MoveD2L src)); 8546 8547 effect(DEF dst, USE src); 8548 8549 ins_cost(FMVX_COST); 8550 8551 format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %} 8552 8553 ins_encode %{ 8554 __ fmv_x_d(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 8555 %} 8556 8557 ins_pipe(fp_d2l); 8558 8559 %} 8560 8561 instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{ 8562 8563 match(Set dst (MoveL2D src)); 8564 8565 effect(DEF dst, USE src); 8566 8567 ins_cost(FMVX_COST); 8568 8569 format %{ "fmv.d.x $dst, $src\t#@MoveD2L_reg_reg" %} 8570 8571 ins_encode %{ 8572 __ fmv_d_x(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 8573 %} 8574 8575 ins_pipe(fp_l2d); 8576 8577 %} 8578 8579 // ============================================================================ 8580 // Compare Instructions which set the result float comparisons in dest register. 8581 8582 instruct cmpF3_reg_reg(iRegINoSp dst, fRegF op1, fRegF op2) 8583 %{ 8584 match(Set dst (CmpF3 op1 op2)); 8585 8586 ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); 8587 format %{ "flt.s $dst, $op2, $op1\t#@cmpF3_reg_reg\n\t" 8588 "bgtz $dst, done\n\t" 8589 "feq.s $dst, $op1, $op2\n\t" 8590 "addi $dst, $dst, -1\t#@cmpF3_reg_reg" 8591 %} 8592 8593 ins_encode %{ 8594 // we want -1 for unordered or less than, 0 for equal and 1 for greater than. 8595 __ float_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), 8596 as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); 8597 %} 8598 8599 ins_pipe(pipe_class_default); 8600 %} 8601 8602 instruct cmpD3_reg_reg(iRegINoSp dst, fRegD op1, fRegD op2) 8603 %{ 8604 match(Set dst (CmpD3 op1 op2)); 8605 8606 ins_cost(XFER_COST * 2 + BRANCH_COST + ALU_COST); 8607 format %{ "flt.d $dst, $op2, $op1\t#@cmpD3_reg_reg\n\t" 8608 "bgtz $dst, done\n\t" 8609 "feq.d $dst, $op1, $op2\n\t" 8610 "addi $dst, $dst, -1\t#@cmpD3_reg_reg" 8611 %} 8612 8613 ins_encode %{ 8614 // we want -1 for unordered or less than, 0 for equal and 1 for greater than. 8615 __ double_compare(as_Register($dst$$reg), as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), -1 /*unordered_result < 0*/); 8616 %} 8617 8618 ins_pipe(pipe_class_default); 8619 %} 8620 8621 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2) 8622 %{ 8623 match(Set dst (CmpL3 op1 op2)); 8624 8625 ins_cost(ALU_COST * 3 + BRANCH_COST); 8626 format %{ "slt $dst, $op2, $op1\t#@cmpL3_reg_reg\n\t" 8627 "bnez $dst, done\n\t" 8628 "slt $dst, $op1, $op2\n\t" 8629 "neg $dst, $dst\t#@cmpL3_reg_reg" 8630 %} 8631 ins_encode %{ 8632 __ cmp_l2i(t0, as_Register($op1$$reg), as_Register($op2$$reg)); 8633 __ mv(as_Register($dst$$reg), t0); 8634 %} 8635 8636 ins_pipe(pipe_class_default); 8637 %} 8638 8639 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q) 8640 %{ 8641 match(Set dst (CmpLTMask p q)); 8642 8643 ins_cost(2 * ALU_COST); 8644 8645 format %{ "slt $dst, $p, $q\t#@cmpLTMask_reg_reg\n\t" 8646 "subw $dst, zr, $dst\t#@cmpLTMask_reg_reg" 8647 %} 8648 8649 ins_encode %{ 8650 __ slt(as_Register($dst$$reg), as_Register($p$$reg), as_Register($q$$reg)); 8651 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 8652 %} 8653 8654 ins_pipe(ialu_reg_reg); 8655 %} 8656 8657 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I op, immI0 zero) 8658 %{ 8659 match(Set dst (CmpLTMask op zero)); 8660 8661 ins_cost(ALU_COST); 8662 8663 format %{ "sraiw $dst, $dst, 31\t#@cmpLTMask_reg_reg" %} 8664 8665 ins_encode %{ 8666 __ sraiw(as_Register($dst$$reg), as_Register($op$$reg), 31); 8667 %} 8668 8669 ins_pipe(ialu_reg_shift); 8670 %} 8671 8672 8673 // ============================================================================ 8674 // Max and Min 8675 8676 instruct minI_reg_reg(iRegINoSp dst, iRegI src) 8677 %{ 8678 match(Set dst (MinI dst src)); 8679 8680 ins_cost(BRANCH_COST + ALU_COST); 8681 format %{ 8682 "ble $dst, $src, skip\t#@minI_reg_reg\n\t" 8683 "mv $dst, $src\n\t" 8684 "skip:" 8685 %} 8686 8687 ins_encode %{ 8688 Label Lskip; 8689 __ ble(as_Register($dst$$reg), as_Register($src$$reg), Lskip); 8690 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8691 __ bind(Lskip); 8692 %} 8693 8694 ins_pipe(pipe_class_compare); 8695 %} 8696 8697 instruct maxI_reg_reg(iRegINoSp dst, iRegI src) 8698 %{ 8699 match(Set dst (MaxI dst src)); 8700 8701 ins_cost(BRANCH_COST + ALU_COST); 8702 format %{ 8703 "bge $dst, $src, skip\t#@maxI_reg_reg\n\t" 8704 "mv $dst, $src\n\t" 8705 "skip:" 8706 %} 8707 8708 ins_encode %{ 8709 Label Lskip; 8710 __ bge(as_Register($dst$$reg), as_Register($src$$reg), Lskip); 8711 __ mv(as_Register($dst$$reg), as_Register($src$$reg)); 8712 __ bind(Lskip); 8713 %} 8714 8715 ins_pipe(pipe_class_compare); 8716 %} 8717 8718 // special case for comparing with zero 8719 // n.b. this is selected in preference to the rule above because it 8720 // avoids loading constant 0 into a source register 8721 8722 instruct minI_reg_zero(iRegINoSp dst, immI0 zero) 8723 %{ 8724 match(Set dst (MinI dst zero)); 8725 match(Set dst (MinI zero dst)); 8726 8727 ins_cost(BRANCH_COST + ALU_COST); 8728 format %{ 8729 "blez $dst, skip\t#@minI_reg_zero\n\t" 8730 "mv $dst, zr\n\t" 8731 "skip:" 8732 %} 8733 8734 ins_encode %{ 8735 Label Lskip; 8736 __ blez(as_Register($dst$$reg), Lskip); 8737 __ mv(as_Register($dst$$reg), zr); 8738 __ bind(Lskip); 8739 %} 8740 8741 ins_pipe(pipe_class_compare); 8742 %} 8743 8744 instruct maxI_reg_zero(iRegINoSp dst, immI0 zero) 8745 %{ 8746 match(Set dst (MaxI dst zero)); 8747 match(Set dst (MaxI zero dst)); 8748 8749 ins_cost(BRANCH_COST + ALU_COST); 8750 format %{ 8751 "bgez $dst, skip\t#@maxI_reg_zero\n\t" 8752 "mv $dst, zr\n\t" 8753 "skip:" 8754 %} 8755 8756 ins_encode %{ 8757 Label Lskip; 8758 __ bgez(as_Register($dst$$reg), Lskip); 8759 __ mv(as_Register($dst$$reg), zr); 8760 __ bind(Lskip); 8761 %} 8762 8763 ins_pipe(pipe_class_compare); 8764 %} 8765 8766 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 8767 %{ 8768 match(Set dst (MinI src1 src2)); 8769 8770 effect(DEF dst, USE src1, USE src2); 8771 8772 ins_cost(BRANCH_COST + ALU_COST * 2); 8773 format %{ 8774 "ble $src1, $src2, Lsrc1.\t#@minI_rReg\n\t" 8775 "mv $dst, $src2\n\t" 8776 "j Ldone\n\t" 8777 "bind Lsrc1\n\t" 8778 "mv $dst, $src1\n\t" 8779 "bind\t#@minI_rReg" 8780 %} 8781 8782 ins_encode %{ 8783 Label Lsrc1, Ldone; 8784 __ ble(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); 8785 __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); 8786 __ j(Ldone); 8787 __ bind(Lsrc1); 8788 __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); 8789 __ bind(Ldone); 8790 %} 8791 8792 ins_pipe(pipe_class_compare); 8793 %} 8794 8795 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2) 8796 %{ 8797 match(Set dst (MaxI src1 src2)); 8798 8799 effect(DEF dst, USE src1, USE src2); 8800 8801 ins_cost(BRANCH_COST + ALU_COST * 2); 8802 format %{ 8803 "bge $src1, $src2, Lsrc1\t#@maxI_rReg\n\t" 8804 "mv $dst, $src2\n\t" 8805 "j Ldone\n\t" 8806 "bind Lsrc1\n\t" 8807 "mv $dst, $src1\n\t" 8808 "bind\t#@maxI_rReg" 8809 %} 8810 8811 ins_encode %{ 8812 Label Lsrc1, Ldone; 8813 __ bge(as_Register($src1$$reg), as_Register($src2$$reg), Lsrc1); 8814 __ mv(as_Register($dst$$reg), as_Register($src2$$reg)); 8815 __ j(Ldone); 8816 __ bind(Lsrc1); 8817 __ mv(as_Register($dst$$reg), as_Register($src1$$reg)); 8818 __ bind(Ldone); 8819 8820 %} 8821 8822 ins_pipe(pipe_class_compare); 8823 %} 8824 8825 // ============================================================================ 8826 // Branch Instructions 8827 // Direct Branch. 8828 instruct branch(label lbl) 8829 %{ 8830 match(Goto); 8831 8832 effect(USE lbl); 8833 8834 ins_cost(BRANCH_COST); 8835 format %{ "j $lbl\t#@branch" %} 8836 8837 ins_encode(riscv_enc_j(lbl)); 8838 8839 ins_pipe(pipe_branch); 8840 %} 8841 8842 // ============================================================================ 8843 // Compare and Branch Instructions 8844 8845 // Patterns for short (< 12KiB) variants 8846 8847 // Compare flags and branch near instructions. 8848 instruct cmpFlag_branch(cmpOpEqNe cmp, rFlagsReg cr, label lbl) %{ 8849 match(If cmp cr); 8850 effect(USE lbl); 8851 8852 ins_cost(BRANCH_COST); 8853 format %{ "b$cmp $cr, zr, $lbl\t#@cmpFlag_branch" %} 8854 8855 ins_encode %{ 8856 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label)); 8857 %} 8858 ins_pipe(pipe_cmpz_branch); 8859 ins_short_branch(1); 8860 %} 8861 8862 // Compare signed int and branch near instructions 8863 instruct cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) 8864 %{ 8865 // Same match rule as `far_cmpI_branch'. 8866 match(If cmp (CmpI op1 op2)); 8867 8868 effect(USE lbl); 8869 8870 ins_cost(BRANCH_COST); 8871 8872 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_branch" %} 8873 8874 ins_encode %{ 8875 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 8876 %} 8877 8878 ins_pipe(pipe_cmp_branch); 8879 ins_short_branch(1); 8880 %} 8881 8882 instruct cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) 8883 %{ 8884 // Same match rule as `far_cmpI_loop'. 8885 match(CountedLoopEnd cmp (CmpI op1 op2)); 8886 8887 effect(USE lbl); 8888 8889 ins_cost(BRANCH_COST); 8890 8891 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpI_loop" %} 8892 8893 ins_encode %{ 8894 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 8895 %} 8896 8897 ins_pipe(pipe_cmp_branch); 8898 ins_short_branch(1); 8899 %} 8900 8901 // Compare unsigned int and branch near instructions 8902 instruct cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) 8903 %{ 8904 // Same match rule as `far_cmpU_branch'. 8905 match(If cmp (CmpU op1 op2)); 8906 8907 effect(USE lbl); 8908 8909 ins_cost(BRANCH_COST); 8910 8911 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpU_branch" %} 8912 8913 ins_encode %{ 8914 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 8915 as_Register($op2$$reg), *($lbl$$label)); 8916 %} 8917 8918 ins_pipe(pipe_cmp_branch); 8919 ins_short_branch(1); 8920 %} 8921 8922 // Compare signed long and branch near instructions 8923 instruct cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) 8924 %{ 8925 // Same match rule as `far_cmpL_branch'. 8926 match(If cmp (CmpL op1 op2)); 8927 8928 effect(USE lbl); 8929 8930 ins_cost(BRANCH_COST); 8931 8932 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_branch" %} 8933 8934 ins_encode %{ 8935 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 8936 %} 8937 8938 ins_pipe(pipe_cmp_branch); 8939 ins_short_branch(1); 8940 %} 8941 8942 instruct cmpL_loop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) 8943 %{ 8944 // Same match rule as `far_cmpL_loop'. 8945 match(CountedLoopEnd cmp (CmpL op1 op2)); 8946 8947 effect(USE lbl); 8948 8949 ins_cost(BRANCH_COST); 8950 8951 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpL_loop" %} 8952 8953 ins_encode %{ 8954 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label)); 8955 %} 8956 8957 ins_pipe(pipe_cmp_branch); 8958 ins_short_branch(1); 8959 %} 8960 8961 // Compare unsigned long and branch near instructions 8962 instruct cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) 8963 %{ 8964 // Same match rule as `far_cmpUL_branch'. 8965 match(If cmp (CmpUL op1 op2)); 8966 8967 effect(USE lbl); 8968 8969 ins_cost(BRANCH_COST); 8970 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpUL_branch" %} 8971 8972 ins_encode %{ 8973 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 8974 as_Register($op2$$reg), *($lbl$$label)); 8975 %} 8976 8977 ins_pipe(pipe_cmp_branch); 8978 ins_short_branch(1); 8979 %} 8980 8981 // Compare pointer and branch near instructions 8982 instruct cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) 8983 %{ 8984 // Same match rule as `far_cmpP_branch'. 8985 match(If cmp (CmpP op1 op2)); 8986 8987 effect(USE lbl); 8988 8989 ins_cost(BRANCH_COST); 8990 8991 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpP_branch" %} 8992 8993 ins_encode %{ 8994 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 8995 as_Register($op2$$reg), *($lbl$$label)); 8996 %} 8997 8998 ins_pipe(pipe_cmp_branch); 8999 ins_short_branch(1); 9000 %} 9001 9002 // Compare narrow pointer and branch near instructions 9003 instruct cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) 9004 %{ 9005 // Same match rule as `far_cmpN_branch'. 9006 match(If cmp (CmpN op1 op2)); 9007 9008 effect(USE lbl); 9009 9010 ins_cost(BRANCH_COST); 9011 9012 format %{ "b$cmp $op1, $op2, $lbl\t#@cmpN_branch" %} 9013 9014 ins_encode %{ 9015 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9016 as_Register($op2$$reg), *($lbl$$label)); 9017 %} 9018 9019 ins_pipe(pipe_cmp_branch); 9020 ins_short_branch(1); 9021 %} 9022 9023 // Compare float and branch near instructions 9024 instruct cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) 9025 %{ 9026 // Same match rule as `far_cmpF_branch'. 9027 match(If cmp (CmpF op1 op2)); 9028 9029 effect(USE lbl); 9030 9031 ins_cost(XFER_COST + BRANCH_COST); 9032 format %{ "float_b$cmp $op1, $op2, $lbl \t#@cmpF_branch"%} 9033 9034 ins_encode %{ 9035 __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), *($lbl$$label)); 9036 %} 9037 9038 ins_pipe(pipe_class_compare); 9039 ins_short_branch(1); 9040 %} 9041 9042 // Compare double and branch near instructions 9043 instruct cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) 9044 %{ 9045 // Same match rule as `far_cmpD_branch'. 9046 match(If cmp (CmpD op1 op2)); 9047 effect(USE lbl); 9048 9049 ins_cost(XFER_COST + BRANCH_COST); 9050 format %{ "double_b$cmp $op1, $op2, $lbl\t#@cmpD_branch"%} 9051 9052 ins_encode %{ 9053 __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), 9054 as_FloatRegister($op2$$reg), *($lbl$$label)); 9055 %} 9056 9057 ins_pipe(pipe_class_compare); 9058 ins_short_branch(1); 9059 %} 9060 9061 // Compare signed int with zero and branch near instructions 9062 instruct cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9063 %{ 9064 // Same match rule as `far_cmpI_reg_imm0_branch'. 9065 match(If cmp (CmpI op1 zero)); 9066 9067 effect(USE op1, USE lbl); 9068 9069 ins_cost(BRANCH_COST); 9070 format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_branch" %} 9071 9072 ins_encode %{ 9073 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9074 %} 9075 9076 ins_pipe(pipe_cmpz_branch); 9077 ins_short_branch(1); 9078 %} 9079 9080 instruct cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9081 %{ 9082 // Same match rule as `far_cmpI_reg_imm0_loop'. 9083 match(CountedLoopEnd cmp (CmpI op1 zero)); 9084 9085 effect(USE op1, USE lbl); 9086 9087 ins_cost(BRANCH_COST); 9088 9089 format %{ "b$cmp $op1, zr, $lbl\t#@cmpI_reg_imm0_loop" %} 9090 9091 ins_encode %{ 9092 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9093 %} 9094 9095 ins_pipe(pipe_cmpz_branch); 9096 ins_short_branch(1); 9097 %} 9098 9099 // Compare unsigned int with zero and branch near instructions 9100 instruct cmpUEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) 9101 %{ 9102 // Same match rule as `far_cmpUEqNeLeGt_reg_imm0_branch'. 9103 match(If cmp (CmpU op1 zero)); 9104 9105 effect(USE op1, USE lbl); 9106 9107 ins_cost(BRANCH_COST); 9108 9109 format %{ "b$cmp $op1, zr, $lbl\t#@cmpUEqNeLeGt_reg_imm0_branch" %} 9110 9111 ins_encode %{ 9112 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9113 %} 9114 9115 ins_pipe(pipe_cmpz_branch); 9116 ins_short_branch(1); 9117 %} 9118 9119 // Compare signed long with zero and branch near instructions 9120 instruct cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9121 %{ 9122 // Same match rule as `far_cmpL_reg_imm0_branch'. 9123 match(If cmp (CmpL op1 zero)); 9124 9125 effect(USE op1, USE lbl); 9126 9127 ins_cost(BRANCH_COST); 9128 9129 format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_branch" %} 9130 9131 ins_encode %{ 9132 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9133 %} 9134 9135 ins_pipe(pipe_cmpz_branch); 9136 ins_short_branch(1); 9137 %} 9138 9139 instruct cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9140 %{ 9141 // Same match rule as `far_cmpL_reg_imm0_loop'. 9142 match(CountedLoopEnd cmp (CmpL op1 zero)); 9143 9144 effect(USE op1, USE lbl); 9145 9146 ins_cost(BRANCH_COST); 9147 9148 format %{ "b$cmp $op1, zr, $lbl\t#@cmpL_reg_imm0_loop" %} 9149 9150 ins_encode %{ 9151 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label)); 9152 %} 9153 9154 ins_pipe(pipe_cmpz_branch); 9155 ins_short_branch(1); 9156 %} 9157 9158 // Compare unsigned long with zero and branch near instructions 9159 instruct cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) 9160 %{ 9161 // Same match rule as `far_cmpULEqNeLeGt_reg_imm0_branch'. 9162 match(If cmp (CmpUL op1 zero)); 9163 9164 effect(USE op1, USE lbl); 9165 9166 ins_cost(BRANCH_COST); 9167 9168 format %{ "b$cmp $op1, zr, $lbl\t#@cmpULEqNeLeGt_reg_imm0_branch" %} 9169 9170 ins_encode %{ 9171 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9172 %} 9173 9174 ins_pipe(pipe_cmpz_branch); 9175 ins_short_branch(1); 9176 %} 9177 9178 // Compare pointer with zero and branch near instructions 9179 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ 9180 // Same match rule as `far_cmpP_reg_imm0_branch'. 9181 match(If cmp (CmpP op1 zero)); 9182 effect(USE lbl); 9183 9184 ins_cost(BRANCH_COST); 9185 format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_imm0_branch" %} 9186 9187 ins_encode %{ 9188 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9189 %} 9190 9191 ins_pipe(pipe_cmpz_branch); 9192 ins_short_branch(1); 9193 %} 9194 9195 // Compare narrow pointer with zero and branch near instructions 9196 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ 9197 // Same match rule as `far_cmpN_reg_imm0_branch'. 9198 match(If cmp (CmpN op1 zero)); 9199 effect(USE lbl); 9200 9201 ins_cost(BRANCH_COST); 9202 9203 format %{ "b$cmp $op1, zr, $lbl\t#@cmpN_imm0_branch" %} 9204 9205 ins_encode %{ 9206 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9207 %} 9208 9209 ins_pipe(pipe_cmpz_branch); 9210 ins_short_branch(1); 9211 %} 9212 9213 // Compare narrow pointer with pointer zero and branch near instructions 9214 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ 9215 // Same match rule as `far_cmpP_narrowOop_imm0_branch'. 9216 match(If cmp (CmpP (DecodeN op1) zero)); 9217 effect(USE lbl); 9218 9219 ins_cost(BRANCH_COST); 9220 format %{ "b$cmp $op1, zr, $lbl\t#@cmpP_narrowOop_imm0_branch" %} 9221 9222 ins_encode %{ 9223 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label)); 9224 %} 9225 9226 ins_pipe(pipe_cmpz_branch); 9227 ins_short_branch(1); 9228 %} 9229 9230 // Patterns for far (20KiB) variants 9231 9232 instruct far_cmpFlag_branch(cmpOp cmp, rFlagsReg cr, label lbl) %{ 9233 match(If cmp cr); 9234 effect(USE lbl); 9235 9236 ins_cost(BRANCH_COST); 9237 format %{ "far_b$cmp $cr, zr, $lbl\t#@far_cmpFlag_branch"%} 9238 9239 ins_encode %{ 9240 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($cr$$reg), *($lbl$$label), /* is_far */ true); 9241 %} 9242 9243 ins_pipe(pipe_cmpz_branch); 9244 %} 9245 9246 // Compare signed int and branch far instructions 9247 instruct far_cmpI_branch(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ 9248 match(If cmp (CmpI op1 op2)); 9249 effect(USE lbl); 9250 9251 ins_cost(BRANCH_COST * 2); 9252 9253 // the format instruction [far_b$cmp] here is be used as two insructions 9254 // in macroassembler: b$not_cmp(op1, op2, done), j($lbl), bind(done) 9255 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_branch" %} 9256 9257 ins_encode %{ 9258 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9259 %} 9260 9261 ins_pipe(pipe_cmp_branch); 9262 %} 9263 9264 instruct far_cmpI_loop(cmpOp cmp, iRegI op1, iRegI op2, label lbl) %{ 9265 match(CountedLoopEnd cmp (CmpI op1 op2)); 9266 effect(USE lbl); 9267 9268 ins_cost(BRANCH_COST * 2); 9269 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpI_loop" %} 9270 9271 ins_encode %{ 9272 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9273 %} 9274 9275 ins_pipe(pipe_cmp_branch); 9276 %} 9277 9278 instruct far_cmpU_branch(cmpOpU cmp, iRegI op1, iRegI op2, label lbl) %{ 9279 match(If cmp (CmpU op1 op2)); 9280 effect(USE lbl); 9281 9282 ins_cost(BRANCH_COST * 2); 9283 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpU_branch" %} 9284 9285 ins_encode %{ 9286 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9287 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9288 %} 9289 9290 ins_pipe(pipe_cmp_branch); 9291 %} 9292 9293 instruct far_cmpL_branch(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ 9294 match(If cmp (CmpL op1 op2)); 9295 effect(USE lbl); 9296 9297 ins_cost(BRANCH_COST * 2); 9298 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_branch" %} 9299 9300 ins_encode %{ 9301 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9302 %} 9303 9304 ins_pipe(pipe_cmp_branch); 9305 %} 9306 9307 instruct far_cmpLloop(cmpOp cmp, iRegL op1, iRegL op2, label lbl) %{ 9308 match(CountedLoopEnd cmp (CmpL op1 op2)); 9309 effect(USE lbl); 9310 9311 ins_cost(BRANCH_COST * 2); 9312 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpL_loop" %} 9313 9314 ins_encode %{ 9315 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9316 %} 9317 9318 ins_pipe(pipe_cmp_branch); 9319 %} 9320 9321 instruct far_cmpUL_branch(cmpOpU cmp, iRegL op1, iRegL op2, label lbl) %{ 9322 match(If cmp (CmpUL op1 op2)); 9323 effect(USE lbl); 9324 9325 ins_cost(BRANCH_COST * 2); 9326 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpUL_branch" %} 9327 9328 ins_encode %{ 9329 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9330 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9331 %} 9332 9333 ins_pipe(pipe_cmp_branch); 9334 %} 9335 9336 instruct far_cmpP_branch(cmpOpU cmp, iRegP op1, iRegP op2, label lbl) 9337 %{ 9338 match(If cmp (CmpP op1 op2)); 9339 9340 effect(USE lbl); 9341 9342 ins_cost(BRANCH_COST * 2); 9343 9344 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpP_branch" %} 9345 9346 ins_encode %{ 9347 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9348 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9349 %} 9350 9351 ins_pipe(pipe_cmp_branch); 9352 %} 9353 9354 instruct far_cmpN_branch(cmpOpU cmp, iRegN op1, iRegN op2, label lbl) 9355 %{ 9356 match(If cmp (CmpN op1 op2)); 9357 9358 effect(USE lbl); 9359 9360 ins_cost(BRANCH_COST * 2); 9361 9362 format %{ "far_b$cmp $op1, $op2, $lbl\t#@far_cmpN_branch" %} 9363 9364 ins_encode %{ 9365 __ cmp_branch($cmp$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, as_Register($op1$$reg), 9366 as_Register($op2$$reg), *($lbl$$label), /* is_far */ true); 9367 %} 9368 9369 ins_pipe(pipe_cmp_branch); 9370 %} 9371 9372 // Float compare and branch instructions 9373 instruct far_cmpF_branch(cmpOp cmp, fRegF op1, fRegF op2, label lbl) 9374 %{ 9375 match(If cmp (CmpF op1 op2)); 9376 9377 effect(USE lbl); 9378 9379 ins_cost(XFER_COST + BRANCH_COST * 2); 9380 format %{ "far_float_b$cmp $op1, $op2, $lbl\t#@far_cmpF_branch"%} 9381 9382 ins_encode %{ 9383 __ float_cmp_branch($cmp$$cmpcode, as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg), 9384 *($lbl$$label), /* is_far */ true); 9385 %} 9386 9387 ins_pipe(pipe_class_compare); 9388 %} 9389 9390 // Double compare and branch instructions 9391 instruct far_cmpD_branch(cmpOp cmp, fRegD op1, fRegD op2, label lbl) 9392 %{ 9393 match(If cmp (CmpD op1 op2)); 9394 effect(USE lbl); 9395 9396 ins_cost(XFER_COST + BRANCH_COST * 2); 9397 format %{ "far_double_b$cmp $op1, $op2, $lbl\t#@far_cmpD_branch"%} 9398 9399 ins_encode %{ 9400 __ float_cmp_branch($cmp$$cmpcode | C2_MacroAssembler::double_branch_mask, as_FloatRegister($op1$$reg), 9401 as_FloatRegister($op2$$reg), *($lbl$$label), /* is_far */ true); 9402 %} 9403 9404 ins_pipe(pipe_class_compare); 9405 %} 9406 9407 instruct far_cmpI_reg_imm0_branch(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9408 %{ 9409 match(If cmp (CmpI op1 zero)); 9410 9411 effect(USE op1, USE lbl); 9412 9413 ins_cost(BRANCH_COST * 2); 9414 9415 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_branch" %} 9416 9417 ins_encode %{ 9418 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9419 %} 9420 9421 ins_pipe(pipe_cmpz_branch); 9422 %} 9423 9424 instruct far_cmpI_reg_imm0_loop(cmpOp cmp, iRegI op1, immI0 zero, label lbl) 9425 %{ 9426 match(CountedLoopEnd cmp (CmpI op1 zero)); 9427 9428 effect(USE op1, USE lbl); 9429 9430 ins_cost(BRANCH_COST * 2); 9431 9432 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpI_reg_imm0_loop" %} 9433 9434 ins_encode %{ 9435 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9436 %} 9437 9438 ins_pipe(pipe_cmpz_branch); 9439 %} 9440 9441 instruct far_cmpUEqNeLeGt_imm0_branch(cmpOpUEqNeLeGt cmp, iRegI op1, immI0 zero, label lbl) 9442 %{ 9443 match(If cmp (CmpU op1 zero)); 9444 9445 effect(USE op1, USE lbl); 9446 9447 ins_cost(BRANCH_COST * 2); 9448 9449 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpUEqNeLeGt_imm0_branch" %} 9450 9451 ins_encode %{ 9452 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9453 %} 9454 9455 ins_pipe(pipe_cmpz_branch); 9456 %} 9457 9458 // compare lt/ge unsigned instructs has no short instruct with same match 9459 instruct far_cmpULtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegI op1, immI0 zero, label lbl) 9460 %{ 9461 match(If cmp (CmpU op1 zero)); 9462 9463 effect(USE op1, USE lbl); 9464 9465 ins_cost(BRANCH_COST); 9466 9467 format %{ "j $lbl if $cmp == ge\t#@far_cmpULtGe_reg_imm0_branch" %} 9468 9469 ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); 9470 9471 ins_pipe(pipe_cmpz_branch); 9472 %} 9473 9474 instruct far_cmpL_reg_imm0_branch(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9475 %{ 9476 match(If cmp (CmpL op1 zero)); 9477 9478 effect(USE op1, USE lbl); 9479 9480 ins_cost(BRANCH_COST * 2); 9481 9482 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_branch" %} 9483 9484 ins_encode %{ 9485 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9486 %} 9487 9488 ins_pipe(pipe_cmpz_branch); 9489 %} 9490 9491 instruct far_cmpL_reg_imm0_loop(cmpOp cmp, iRegL op1, immL0 zero, label lbl) 9492 %{ 9493 match(CountedLoopEnd cmp (CmpL op1 zero)); 9494 9495 effect(USE op1, USE lbl); 9496 9497 ins_cost(BRANCH_COST * 2); 9498 9499 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpL_reg_imm0_loop" %} 9500 9501 ins_encode %{ 9502 __ cmp_branch($cmp$$cmpcode, as_Register($op1$$reg), zr, *($lbl$$label), /* is_far */ true); 9503 %} 9504 9505 ins_pipe(pipe_cmpz_branch); 9506 %} 9507 9508 instruct far_cmpULEqNeLeGt_reg_imm0_branch(cmpOpUEqNeLeGt cmp, iRegL op1, immL0 zero, label lbl) 9509 %{ 9510 match(If cmp (CmpUL op1 zero)); 9511 9512 effect(USE op1, USE lbl); 9513 9514 ins_cost(BRANCH_COST * 2); 9515 9516 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpULEqNeLeGt_reg_imm0_branch" %} 9517 9518 ins_encode %{ 9519 __ enc_cmpUEqNeLeGt_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9520 %} 9521 9522 ins_pipe(pipe_cmpz_branch); 9523 %} 9524 9525 // compare lt/ge unsigned instructs has no short instruct with same match 9526 instruct far_cmpULLtGe_reg_imm0_branch(cmpOpULtGe cmp, iRegL op1, immL0 zero, label lbl) 9527 %{ 9528 match(If cmp (CmpUL op1 zero)); 9529 9530 effect(USE op1, USE lbl); 9531 9532 ins_cost(BRANCH_COST); 9533 9534 format %{ "j $lbl if $cmp == ge\t#@far_cmpULLtGe_reg_imm0_branch" %} 9535 9536 ins_encode(riscv_enc_far_cmpULtGe_imm0_branch(cmp, op1, lbl)); 9537 9538 ins_pipe(pipe_cmpz_branch); 9539 %} 9540 9541 instruct far_cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 zero, label lbl) %{ 9542 match(If cmp (CmpP op1 zero)); 9543 effect(USE lbl); 9544 9545 ins_cost(BRANCH_COST * 2); 9546 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_imm0_branch" %} 9547 9548 ins_encode %{ 9549 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9550 %} 9551 9552 ins_pipe(pipe_cmpz_branch); 9553 %} 9554 9555 instruct far_cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 zero, label lbl) %{ 9556 match(If cmp (CmpN op1 zero)); 9557 effect(USE lbl); 9558 9559 ins_cost(BRANCH_COST * 2); 9560 9561 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpN_imm0_branch" %} 9562 9563 ins_encode %{ 9564 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9565 %} 9566 9567 ins_pipe(pipe_cmpz_branch); 9568 %} 9569 9570 instruct far_cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN op1, immP0 zero, label lbl) %{ 9571 match(If cmp (CmpP (DecodeN op1) zero)); 9572 effect(USE lbl); 9573 9574 ins_cost(BRANCH_COST * 2); 9575 format %{ "far_b$cmp $op1, zr, $lbl\t#@far_cmpP_narrowOop_imm0_branch" %} 9576 9577 ins_encode %{ 9578 __ enc_cmpEqNe_imm0_branch($cmp$$cmpcode, as_Register($op1$$reg), *($lbl$$label), /* is_far */ true); 9579 %} 9580 9581 ins_pipe(pipe_cmpz_branch); 9582 %} 9583 9584 // ============================================================================ 9585 // Conditional Move Instructions 9586 instruct cmovI_cmpI(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOp cop) %{ 9587 match(Set dst (CMoveI (Binary cop (CmpI op1 op2)) (Binary dst src))); 9588 ins_cost(ALU_COST + BRANCH_COST); 9589 9590 format %{ 9591 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpI\n\t" 9592 %} 9593 9594 ins_encode %{ 9595 __ enc_cmove($cop$$cmpcode, 9596 as_Register($op1$$reg), as_Register($op2$$reg), 9597 as_Register($dst$$reg), as_Register($src$$reg)); 9598 %} 9599 9600 ins_pipe(pipe_class_compare); 9601 %} 9602 9603 instruct cmovI_cmpU(iRegINoSp dst, iRegI src, iRegI op1, iRegI op2, cmpOpU cop) %{ 9604 match(Set dst (CMoveI (Binary cop (CmpU op1 op2)) (Binary dst src))); 9605 ins_cost(ALU_COST + BRANCH_COST); 9606 9607 format %{ 9608 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpU\n\t" 9609 %} 9610 9611 ins_encode %{ 9612 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9613 as_Register($op1$$reg), as_Register($op2$$reg), 9614 as_Register($dst$$reg), as_Register($src$$reg)); 9615 %} 9616 9617 ins_pipe(pipe_class_compare); 9618 %} 9619 9620 instruct cmovI_cmpL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOp cop) %{ 9621 match(Set dst (CMoveI (Binary cop (CmpL op1 op2)) (Binary dst src))); 9622 ins_cost(ALU_COST + BRANCH_COST); 9623 9624 format %{ 9625 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpL\n\t" 9626 %} 9627 9628 ins_encode %{ 9629 __ enc_cmove($cop$$cmpcode, 9630 as_Register($op1$$reg), as_Register($op2$$reg), 9631 as_Register($dst$$reg), as_Register($src$$reg)); 9632 %} 9633 9634 ins_pipe(pipe_class_compare); 9635 %} 9636 9637 instruct cmovI_cmpUL(iRegINoSp dst, iRegI src, iRegL op1, iRegL op2, cmpOpU cop) %{ 9638 match(Set dst (CMoveI (Binary cop (CmpUL op1 op2)) (Binary dst src))); 9639 ins_cost(ALU_COST + BRANCH_COST); 9640 9641 format %{ 9642 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovI_cmpUL\n\t" 9643 %} 9644 9645 ins_encode %{ 9646 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9647 as_Register($op1$$reg), as_Register($op2$$reg), 9648 as_Register($dst$$reg), as_Register($src$$reg)); 9649 %} 9650 9651 ins_pipe(pipe_class_compare); 9652 %} 9653 9654 instruct cmovL_cmpL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOp cop) %{ 9655 match(Set dst (CMoveL (Binary cop (CmpL op1 op2)) (Binary dst src))); 9656 ins_cost(ALU_COST + BRANCH_COST); 9657 9658 format %{ 9659 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpL\n\t" 9660 %} 9661 9662 ins_encode %{ 9663 __ enc_cmove($cop$$cmpcode, 9664 as_Register($op1$$reg), as_Register($op2$$reg), 9665 as_Register($dst$$reg), as_Register($src$$reg)); 9666 %} 9667 9668 ins_pipe(pipe_class_compare); 9669 %} 9670 9671 instruct cmovL_cmpUL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOpU cop) %{ 9672 match(Set dst (CMoveL (Binary cop (CmpUL op1 op2)) (Binary dst src))); 9673 ins_cost(ALU_COST + BRANCH_COST); 9674 9675 format %{ 9676 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpUL\n\t" 9677 %} 9678 9679 ins_encode %{ 9680 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9681 as_Register($op1$$reg), as_Register($op2$$reg), 9682 as_Register($dst$$reg), as_Register($src$$reg)); 9683 %} 9684 9685 ins_pipe(pipe_class_compare); 9686 %} 9687 9688 instruct cmovL_cmpI(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOp cop) %{ 9689 match(Set dst (CMoveL (Binary cop (CmpI op1 op2)) (Binary dst src))); 9690 ins_cost(ALU_COST + BRANCH_COST); 9691 9692 format %{ 9693 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpI\n\t" 9694 %} 9695 9696 ins_encode %{ 9697 __ enc_cmove($cop$$cmpcode, 9698 as_Register($op1$$reg), as_Register($op2$$reg), 9699 as_Register($dst$$reg), as_Register($src$$reg)); 9700 %} 9701 9702 ins_pipe(pipe_class_compare); 9703 %} 9704 9705 instruct cmovL_cmpU(iRegLNoSp dst, iRegL src, iRegI op1, iRegI op2, cmpOpU cop) %{ 9706 match(Set dst (CMoveL (Binary cop (CmpU op1 op2)) (Binary dst src))); 9707 ins_cost(ALU_COST + BRANCH_COST); 9708 9709 format %{ 9710 "CMove $dst, ($op1 $cop $op2), $dst, $src\t#@cmovL_cmpU\n\t" 9711 %} 9712 9713 ins_encode %{ 9714 __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, 9715 as_Register($op1$$reg), as_Register($op2$$reg), 9716 as_Register($dst$$reg), as_Register($src$$reg)); 9717 %} 9718 9719 ins_pipe(pipe_class_compare); 9720 %} 9721 9722 // ============================================================================ 9723 // Procedure Call/Return Instructions 9724 9725 // Call Java Static Instruction 9726 // Note: If this code changes, the corresponding ret_addr_offset() and 9727 // compute_padding() functions will have to be adjusted. 9728 instruct CallStaticJavaDirect(method meth) 9729 %{ 9730 match(CallStaticJava); 9731 9732 effect(USE meth); 9733 9734 ins_cost(BRANCH_COST); 9735 9736 format %{ "CALL,static $meth\t#@CallStaticJavaDirect" %} 9737 9738 ins_encode(riscv_enc_java_static_call(meth), 9739 riscv_enc_call_epilog); 9740 9741 ins_pipe(pipe_class_call); 9742 ins_alignment(4); 9743 %} 9744 9745 // TO HERE 9746 9747 // Call Java Dynamic Instruction 9748 // Note: If this code changes, the corresponding ret_addr_offset() and 9749 // compute_padding() functions will have to be adjusted. 9750 instruct CallDynamicJavaDirect(method meth, rFlagsReg cr) 9751 %{ 9752 match(CallDynamicJava); 9753 9754 effect(USE meth, KILL cr); 9755 9756 ins_cost(BRANCH_COST + ALU_COST * 6); 9757 9758 format %{ "CALL,dynamic $meth\t#@CallDynamicJavaDirect" %} 9759 9760 ins_encode(riscv_enc_java_dynamic_call(meth), 9761 riscv_enc_call_epilog); 9762 9763 ins_pipe(pipe_class_call); 9764 ins_alignment(4); 9765 %} 9766 9767 // Call Runtime Instruction 9768 9769 instruct CallRuntimeDirect(method meth, rFlagsReg cr) 9770 %{ 9771 match(CallRuntime); 9772 9773 effect(USE meth, KILL cr); 9774 9775 ins_cost(BRANCH_COST); 9776 9777 format %{ "CALL, runtime $meth\t#@CallRuntimeDirect" %} 9778 9779 ins_encode(riscv_enc_java_to_runtime(meth)); 9780 9781 ins_pipe(pipe_class_call); 9782 %} 9783 9784 // Call Runtime Instruction 9785 9786 instruct CallLeafDirect(method meth, rFlagsReg cr) 9787 %{ 9788 match(CallLeaf); 9789 9790 effect(USE meth, KILL cr); 9791 9792 ins_cost(BRANCH_COST); 9793 9794 format %{ "CALL, runtime leaf $meth\t#@CallLeafDirect" %} 9795 9796 ins_encode(riscv_enc_java_to_runtime(meth)); 9797 9798 ins_pipe(pipe_class_call); 9799 %} 9800 9801 // Call Runtime Instruction 9802 9803 instruct CallLeafNoFPDirect(method meth, rFlagsReg cr) 9804 %{ 9805 match(CallLeafNoFP); 9806 9807 effect(USE meth, KILL cr); 9808 9809 ins_cost(BRANCH_COST); 9810 9811 format %{ "CALL, runtime leaf nofp $meth\t#@CallLeafNoFPDirect" %} 9812 9813 ins_encode(riscv_enc_java_to_runtime(meth)); 9814 9815 ins_pipe(pipe_class_call); 9816 %} 9817 9818 // ============================================================================ 9819 // Partial Subtype Check 9820 // 9821 // superklass array for an instance of the superklass. Set a hidden 9822 // internal cache on a hit (cache is checked with exposed code in 9823 // gen_subtype_check()). Return zero for a hit. The encoding 9824 // ALSO sets flags. 9825 9826 instruct partialSubtypeCheck(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, rFlagsReg cr) 9827 %{ 9828 match(Set result (PartialSubtypeCheck sub super)); 9829 effect(KILL tmp, KILL cr); 9830 9831 ins_cost(2 * STORE_COST + 3 * LOAD_COST + 4 * ALU_COST + BRANCH_COST * 4); 9832 format %{ "partialSubtypeCheck $result, $sub, $super\t#@partialSubtypeCheck" %} 9833 9834 ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); 9835 9836 opcode(0x1); // Force zero of result reg on hit 9837 9838 ins_pipe(pipe_class_memory); 9839 %} 9840 9841 instruct partialSubtypeCheckVsZero(iRegP_R15 result, iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tmp, 9842 immP0 zero, rFlagsReg cr) 9843 %{ 9844 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 9845 effect(KILL tmp, KILL result); 9846 9847 ins_cost(2 * STORE_COST + 3 * LOAD_COST + 4 * ALU_COST + BRANCH_COST * 4); 9848 format %{ "partialSubtypeCheck $result, $sub, $super == 0\t#@partialSubtypeCheckVsZero" %} 9849 9850 ins_encode(riscv_enc_partial_subtype_check(sub, super, tmp, result)); 9851 9852 opcode(0x0); // Don't zero result reg on hit 9853 9854 ins_pipe(pipe_class_memory); 9855 %} 9856 9857 instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9858 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 9859 %{ 9860 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU); 9861 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 9862 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 9863 9864 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareU" %} 9865 ins_encode %{ 9866 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 9867 __ string_compare($str1$$Register, $str2$$Register, 9868 $cnt1$$Register, $cnt2$$Register, $result$$Register, 9869 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 9870 StrIntrinsicNode::UU); 9871 %} 9872 ins_pipe(pipe_class_memory); 9873 %} 9874 9875 instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9876 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 9877 %{ 9878 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL); 9879 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 9880 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 9881 9882 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareL" %} 9883 ins_encode %{ 9884 __ string_compare($str1$$Register, $str2$$Register, 9885 $cnt1$$Register, $cnt2$$Register, $result$$Register, 9886 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 9887 StrIntrinsicNode::LL); 9888 %} 9889 ins_pipe(pipe_class_memory); 9890 %} 9891 9892 instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9893 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, rFlagsReg cr) 9894 %{ 9895 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL); 9896 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 9897 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 9898 9899 format %{"String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareUL" %} 9900 ins_encode %{ 9901 __ string_compare($str1$$Register, $str2$$Register, 9902 $cnt1$$Register, $cnt2$$Register, $result$$Register, 9903 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 9904 StrIntrinsicNode::UL); 9905 %} 9906 ins_pipe(pipe_class_memory); 9907 %} 9908 9909 instruct string_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9910 iRegI_R10 result, iRegP_R28 tmp1, iRegL_R29 tmp2, iRegL_R30 tmp3, 9911 rFlagsReg cr) 9912 %{ 9913 predicate(!UseRVV && ((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU); 9914 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 9915 effect(KILL tmp1, KILL tmp2, KILL tmp3, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 9916 9917 format %{ "String Compare $str1, $cnt1, $str2, $cnt2 -> $result\t#@string_compareLU" %} 9918 ins_encode %{ 9919 __ string_compare($str1$$Register, $str2$$Register, 9920 $cnt1$$Register, $cnt2$$Register, $result$$Register, 9921 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 9922 StrIntrinsicNode::LU); 9923 %} 9924 ins_pipe(pipe_class_memory); 9925 %} 9926 9927 instruct string_indexofUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9928 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 9929 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 9930 %{ 9931 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 9932 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 9933 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 9934 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 9935 9936 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} 9937 ins_encode %{ 9938 __ string_indexof($str1$$Register, $str2$$Register, 9939 $cnt1$$Register, $cnt2$$Register, 9940 $tmp1$$Register, $tmp2$$Register, 9941 $tmp3$$Register, $tmp4$$Register, 9942 $tmp5$$Register, $tmp6$$Register, 9943 $result$$Register, StrIntrinsicNode::UU); 9944 %} 9945 ins_pipe(pipe_class_memory); 9946 %} 9947 9948 instruct string_indexofLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9949 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 9950 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 9951 %{ 9952 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 9953 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 9954 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 9955 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 9956 9957 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} 9958 ins_encode %{ 9959 __ string_indexof($str1$$Register, $str2$$Register, 9960 $cnt1$$Register, $cnt2$$Register, 9961 $tmp1$$Register, $tmp2$$Register, 9962 $tmp3$$Register, $tmp4$$Register, 9963 $tmp5$$Register, $tmp6$$Register, 9964 $result$$Register, StrIntrinsicNode::LL); 9965 %} 9966 ins_pipe(pipe_class_memory); 9967 %} 9968 9969 instruct string_indexofUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2, 9970 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 9971 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) 9972 %{ 9973 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 9974 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 9975 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, TEMP_DEF result, 9976 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); 9977 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} 9978 9979 ins_encode %{ 9980 __ string_indexof($str1$$Register, $str2$$Register, 9981 $cnt1$$Register, $cnt2$$Register, 9982 $tmp1$$Register, $tmp2$$Register, 9983 $tmp3$$Register, $tmp4$$Register, 9984 $tmp5$$Register, $tmp6$$Register, 9985 $result$$Register, StrIntrinsicNode::UL); 9986 %} 9987 ins_pipe(pipe_class_memory); 9988 %} 9989 9990 instruct string_indexof_conUU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 9991 immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 9992 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 9993 %{ 9994 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 9995 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 9996 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 9997 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 9998 9999 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} 10000 10001 ins_encode %{ 10002 int icnt2 = (int)$int_cnt2$$constant; 10003 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10004 $cnt1$$Register, zr, 10005 $tmp1$$Register, $tmp2$$Register, 10006 $tmp3$$Register, $tmp4$$Register, 10007 icnt2, $result$$Register, StrIntrinsicNode::UU); 10008 %} 10009 ins_pipe(pipe_class_memory); 10010 %} 10011 10012 instruct string_indexof_conLL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 10013 immI_le_4 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10014 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10015 %{ 10016 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 10017 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10018 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 10019 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10020 10021 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} 10022 ins_encode %{ 10023 int icnt2 = (int)$int_cnt2$$constant; 10024 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10025 $cnt1$$Register, zr, 10026 $tmp1$$Register, $tmp2$$Register, 10027 $tmp3$$Register, $tmp4$$Register, 10028 icnt2, $result$$Register, StrIntrinsicNode::LL); 10029 %} 10030 ins_pipe(pipe_class_memory); 10031 %} 10032 10033 instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, 10034 immI_1 int_cnt2, iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10035 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10036 %{ 10037 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 10038 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10039 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP_DEF result, 10040 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10041 10042 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} 10043 ins_encode %{ 10044 int icnt2 = (int)$int_cnt2$$constant; 10045 __ string_indexof_linearscan($str1$$Register, $str2$$Register, 10046 $cnt1$$Register, zr, 10047 $tmp1$$Register, $tmp2$$Register, 10048 $tmp3$$Register, $tmp4$$Register, 10049 icnt2, $result$$Register, StrIntrinsicNode::UL); 10050 %} 10051 ins_pipe(pipe_class_memory); 10052 %} 10053 10054 instruct stringU_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, 10055 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10056 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10057 %{ 10058 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10059 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 10060 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, 10061 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10062 10063 format %{ "StringUTF16 IndexOf char[] $str1, $cnt1, $ch -> $result" %} 10064 ins_encode %{ 10065 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 10066 $result$$Register, $tmp1$$Register, $tmp2$$Register, 10067 $tmp3$$Register, $tmp4$$Register, false /* isU */); 10068 %} 10069 ins_pipe(pipe_class_memory); 10070 %} 10071 10072 10073 instruct stringL_indexof_char(iRegP_R11 str1, iRegI_R12 cnt1, iRegI_R13 ch, 10074 iRegI_R10 result, iRegINoSp tmp1, iRegINoSp tmp2, 10075 iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 10076 %{ 10077 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10078 predicate(!UseRVV && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 10079 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP_DEF result, 10080 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 10081 10082 format %{ "StringLatin1 IndexOf char[] $str1, $cnt1, $ch -> $result" %} 10083 ins_encode %{ 10084 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 10085 $result$$Register, $tmp1$$Register, $tmp2$$Register, 10086 $tmp3$$Register, $tmp4$$Register, true /* isL */); 10087 %} 10088 ins_pipe(pipe_class_memory); 10089 %} 10090 10091 // clearing of an array 10092 instruct clearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, iRegP_R30 tmp1, 10093 iRegP_R31 tmp2, Universe dummy) 10094 %{ 10095 // temp registers must match the one used in StubGenerator::generate_zero_blocks() 10096 predicate(UseBlockZeroing || !UseRVV); 10097 match(Set dummy (ClearArray cnt base)); 10098 effect(USE_KILL cnt, USE_KILL base, TEMP tmp1, TEMP tmp2); 10099 10100 ins_cost(4 * DEFAULT_COST); 10101 format %{ "ClearArray $cnt, $base\t#@clearArray_reg_reg" %} 10102 10103 ins_encode %{ 10104 address tpc = __ zero_words($base$$Register, $cnt$$Register); 10105 if (tpc == NULL) { 10106 ciEnv::current()->record_failure("CodeCache is full"); 10107 return; 10108 } 10109 %} 10110 10111 ins_pipe(pipe_class_memory); 10112 %} 10113 10114 instruct clearArray_imm_reg(immL cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr) 10115 %{ 10116 predicate(!UseRVV && (uint64_t)n->in(2)->get_long() 10117 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); 10118 match(Set dummy (ClearArray cnt base)); 10119 effect(USE_KILL base, KILL cr); 10120 10121 ins_cost(4 * DEFAULT_COST); 10122 format %{ "ClearArray $cnt, $base\t#@clearArray_imm_reg" %} 10123 10124 ins_encode %{ 10125 __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 10126 %} 10127 10128 ins_pipe(pipe_class_memory); 10129 %} 10130 10131 instruct string_equalsL(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, 10132 iRegI_R10 result, rFlagsReg cr) 10133 %{ 10134 predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 10135 match(Set result (StrEquals (Binary str1 str2) cnt)); 10136 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 10137 10138 format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsL" %} 10139 ins_encode %{ 10140 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 10141 __ string_equals($str1$$Register, $str2$$Register, 10142 $result$$Register, $cnt$$Register, 1); 10143 %} 10144 ins_pipe(pipe_class_memory); 10145 %} 10146 10147 instruct string_equalsU(iRegP_R11 str1, iRegP_R13 str2, iRegI_R14 cnt, 10148 iRegI_R10 result, rFlagsReg cr) 10149 %{ 10150 predicate(!UseRVV && ((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 10151 match(Set result (StrEquals (Binary str1 str2) cnt)); 10152 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 10153 10154 format %{ "String Equals $str1, $str2, $cnt -> $result\t#@string_equalsU" %} 10155 ins_encode %{ 10156 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 10157 __ string_equals($str1$$Register, $str2$$Register, 10158 $result$$Register, $cnt$$Register, 2); 10159 %} 10160 ins_pipe(pipe_class_memory); 10161 %} 10162 10163 instruct array_equalsB(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, 10164 iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3, 10165 iRegP_R16 tmp4, iRegP_R28 tmp5, rFlagsReg cr) 10166 %{ 10167 predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10168 match(Set result (AryEq ary1 ary2)); 10169 effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL tmp5, KILL cr); 10170 10171 format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsB // KILL $tmp5" %} 10172 ins_encode %{ 10173 __ arrays_equals($ary1$$Register, $ary2$$Register, 10174 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, 10175 $result$$Register, $tmp5$$Register, 1); 10176 %} 10177 ins_pipe(pipe_class_memory); 10178 %} 10179 10180 instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, 10181 iRegP_R13 tmp1, iRegP_R14 tmp2, iRegP_R15 tmp3, 10182 iRegP_R16 tmp4, iRegP_R28 tmp5, rFlagsReg cr) 10183 %{ 10184 predicate(!UseRVV && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10185 match(Set result (AryEq ary1 ary2)); 10186 effect(USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL tmp5, KILL cr); 10187 10188 format %{ "Array Equals $ary1, ary2 -> $result\t#@array_equalsC // KILL $tmp5" %} 10189 ins_encode %{ 10190 __ arrays_equals($ary1$$Register, $ary2$$Register, 10191 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, 10192 $result$$Register, $tmp5$$Register, 2); 10193 %} 10194 ins_pipe(pipe_class_memory); 10195 %} 10196 10197 // ============================================================================ 10198 // Safepoint Instructions 10199 10200 instruct safePoint(iRegP poll) 10201 %{ 10202 match(SafePoint poll); 10203 10204 ins_cost(2 * LOAD_COST); 10205 format %{ 10206 "lwu zr, [$poll]\t# Safepoint: poll for GC, #@safePoint" 10207 %} 10208 ins_encode %{ 10209 __ read_polling_page(as_Register($poll$$reg), 0, relocInfo::poll_type); 10210 %} 10211 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 10212 %} 10213 10214 // ============================================================================ 10215 // This name is KNOWN by the ADLC and cannot be changed. 10216 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 10217 // for this guy. 10218 instruct tlsLoadP(javaThread_RegP dst) 10219 %{ 10220 match(Set dst (ThreadLocal)); 10221 10222 ins_cost(0); 10223 10224 format %{ " -- \t// $dst=Thread::current(), empty, #@tlsLoadP" %} 10225 10226 size(0); 10227 10228 ins_encode( /*empty*/ ); 10229 10230 ins_pipe(pipe_class_empty); 10231 %} 10232 10233 // inlined locking and unlocking 10234 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers 10235 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3) 10236 %{ 10237 match(Set cr (FastLock object box)); 10238 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 10239 10240 ins_cost(LOAD_COST * 2 + STORE_COST * 3 + ALU_COST * 6 + BRANCH_COST * 3); 10241 format %{ "fastlock $object,$box\t! kills $tmp1,$tmp2,$tmp3, #@cmpFastLock" %} 10242 10243 ins_encode %{ 10244 __ fast_lock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register); 10245 %} 10246 10247 ins_pipe(pipe_serial); 10248 %} 10249 10250 // using t1 as the 'flag' register to bridge the BoolNode producers and consumers 10251 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp1, iRegPNoSp tmp2) 10252 %{ 10253 match(Set cr (FastUnlock object box)); 10254 effect(TEMP tmp1, TEMP tmp2); 10255 10256 ins_cost(LOAD_COST * 2 + STORE_COST + ALU_COST * 2 + BRANCH_COST * 4); 10257 format %{ "fastunlock $object,$box\t! kills $tmp1, $tmp2, #@cmpFastUnlock" %} 10258 10259 ins_encode %{ 10260 __ fast_unlock($object$$Register, $box$$Register, $tmp1$$Register, $tmp2$$Register); 10261 %} 10262 10263 ins_pipe(pipe_serial); 10264 %} 10265 10266 // Tail Call; Jump from runtime stub to Java code. 10267 // Also known as an 'interprocedural jump'. 10268 // Target of jump will eventually return to caller. 10269 // TailJump below removes the return address. 10270 // Don't use fp for 'jump_target' because a MachEpilogNode has already been 10271 // emitted just above the TailCall which has reset fp to the caller state. 10272 instruct TailCalljmpInd(iRegPNoSpNoFp jump_target, inline_cache_RegP method_oop) 10273 %{ 10274 match(TailCall jump_target method_oop); 10275 10276 ins_cost(BRANCH_COST); 10277 10278 format %{ "jalr $jump_target\t# $method_oop holds method oop, #@TailCalljmpInd." %} 10279 10280 ins_encode(riscv_enc_tail_call(jump_target)); 10281 10282 ins_pipe(pipe_class_call); 10283 %} 10284 10285 instruct TailjmpInd(iRegPNoSpNoFp jump_target, iRegP_R10 ex_oop) 10286 %{ 10287 match(TailJump jump_target ex_oop); 10288 10289 ins_cost(ALU_COST + BRANCH_COST); 10290 10291 format %{ "jalr $jump_target\t# $ex_oop holds exception oop, #@TailjmpInd." %} 10292 10293 ins_encode(riscv_enc_tail_jmp(jump_target)); 10294 10295 ins_pipe(pipe_class_call); 10296 %} 10297 10298 // Create exception oop: created by stack-crawling runtime code. 10299 // Created exception is now available to this handler, and is setup 10300 // just prior to jumping to this handler. No code emitted. 10301 instruct CreateException(iRegP_R10 ex_oop) 10302 %{ 10303 match(Set ex_oop (CreateEx)); 10304 10305 ins_cost(0); 10306 format %{ " -- \t// exception oop; no code emitted, #@CreateException" %} 10307 10308 size(0); 10309 10310 ins_encode( /*empty*/ ); 10311 10312 ins_pipe(pipe_class_empty); 10313 %} 10314 10315 // Rethrow exception: The exception oop will come in the first 10316 // argument position. Then JUMP (not call) to the rethrow stub code. 10317 instruct RethrowException() 10318 %{ 10319 match(Rethrow); 10320 10321 ins_cost(BRANCH_COST); 10322 10323 format %{ "j rethrow_stub\t#@RethrowException" %} 10324 10325 ins_encode(riscv_enc_rethrow()); 10326 10327 ins_pipe(pipe_class_call); 10328 %} 10329 10330 // Return Instruction 10331 // epilog node loads ret address into ra as part of frame pop 10332 instruct Ret() 10333 %{ 10334 match(Return); 10335 10336 ins_cost(BRANCH_COST); 10337 format %{ "ret\t// return register, #@Ret" %} 10338 10339 ins_encode(riscv_enc_ret()); 10340 10341 ins_pipe(pipe_branch); 10342 %} 10343 10344 // Die now. 10345 instruct ShouldNotReachHere() %{ 10346 match(Halt); 10347 10348 ins_cost(BRANCH_COST); 10349 10350 format %{ "#@ShouldNotReachHere" %} 10351 10352 ins_encode %{ 10353 if (is_reachable()) { 10354 __ stop(_halt_reason); 10355 } 10356 %} 10357 10358 ins_pipe(pipe_class_default); 10359 %} 10360 10361 10362 //----------PEEPHOLE RULES----------------------------------------------------- 10363 // These must follow all instruction definitions as they use the names 10364 // defined in the instructions definitions. 10365 // 10366 // peepmatch ( root_instr_name [preceding_instruction]* ); 10367 // 10368 // peepconstraint %{ 10369 // (instruction_number.operand_name relational_op instruction_number.operand_name 10370 // [, ...] ); 10371 // // instruction numbers are zero-based using left to right order in peepmatch 10372 // 10373 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 10374 // // provide an instruction_number.operand_name for each operand that appears 10375 // // in the replacement instruction's match rule 10376 // 10377 // ---------VM FLAGS--------------------------------------------------------- 10378 // 10379 // All peephole optimizations can be turned off using -XX:-OptoPeephole 10380 // 10381 // Each peephole rule is given an identifying number starting with zero and 10382 // increasing by one in the order seen by the parser. An individual peephole 10383 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 10384 // on the command-line. 10385 // 10386 // ---------CURRENT LIMITATIONS---------------------------------------------- 10387 // 10388 // Only match adjacent instructions in same basic block 10389 // Only equality constraints 10390 // Only constraints between operands, not (0.dest_reg == RAX_enc) 10391 // Only one replacement instruction 10392 // 10393 //----------SMARTSPILL RULES--------------------------------------------------- 10394 // These must follow all instruction definitions as they use the names 10395 // defined in the instructions definitions. 10396 10397 // Local Variables: 10398 // mode: c++ 10399 // End: