1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,8824 @@ 1.4 +// 1.5 +// Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 +// 1.8 +// This code is free software; you can redistribute it and/or modify it 1.9 +// under the terms of the GNU General Public License version 2 only, as 1.10 +// published by the Free Software Foundation. 1.11 +// 1.12 +// This code is distributed in the hope that it will be useful, but WITHOUT 1.13 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 +// version 2 for more details (a copy is included in the LICENSE file that 1.16 +// accompanied this code). 1.17 +// 1.18 +// You should have received a copy of the GNU General Public License version 1.19 +// 2 along with this work; if not, write to the Free Software Foundation, 1.20 +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 +// 1.22 +// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 +// CA 95054 USA or visit www.sun.com if you need additional information or 1.24 +// have any questions. 1.25 +// 1.26 +// 1.27 + 1.28 +// SPARC Architecture Description File 1.29 + 1.30 +//----------REGISTER DEFINITION BLOCK------------------------------------------ 1.31 +// This information is used by the matcher and the register allocator to 1.32 +// describe individual registers and classes of registers within the target 1.33 +// archtecture. 1.34 +register %{ 1.35 +//----------Architecture Description Register Definitions---------------------- 1.36 +// General Registers 1.37 +// "reg_def" name ( register save type, C convention save type, 1.38 +// ideal register type, encoding, vm name ); 1.39 +// Register Save Types: 1.40 +// 1.41 +// NS = No-Save: The register allocator assumes that these registers 1.42 +// can be used without saving upon entry to the method, & 1.43 +// that they do not need to be saved at call sites. 1.44 +// 1.45 +// SOC = Save-On-Call: The register allocator assumes that these registers 1.46 +// can be used without saving upon entry to the method, 1.47 +// but that they must be saved at call sites. 1.48 +// 1.49 +// SOE = Save-On-Entry: The register allocator assumes that these registers 1.50 +// must be saved before using them upon entry to the 1.51 +// method, but they do not need to be saved at call 1.52 +// sites. 1.53 +// 1.54 +// AS = Always-Save: The register allocator assumes that these registers 1.55 +// must be saved before using them upon entry to the 1.56 +// method, & that they must be saved at call sites. 1.57 +// 1.58 +// Ideal Register Type is used to determine how to save & restore a 1.59 +// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 1.60 +// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 1.61 +// 1.62 +// The encoding number is the actual bit-pattern placed into the opcodes. 1.63 + 1.64 + 1.65 +// ---------------------------- 1.66 +// Integer/Long Registers 1.67 +// ---------------------------- 1.68 + 1.69 +// Need to expose the hi/lo aspect of 64-bit registers 1.70 +// This register set is used for both the 64-bit build and 1.71 +// the 32-bit build with 1-register longs. 1.72 + 1.73 +// Global Registers 0-7 1.74 +reg_def R_G0H( NS, NS, Op_RegI,128, G0->as_VMReg()->next()); 1.75 +reg_def R_G0 ( NS, NS, Op_RegI, 0, G0->as_VMReg()); 1.76 +reg_def R_G1H(SOC, SOC, Op_RegI,129, G1->as_VMReg()->next()); 1.77 +reg_def R_G1 (SOC, SOC, Op_RegI, 1, G1->as_VMReg()); 1.78 +reg_def R_G2H( NS, NS, Op_RegI,130, G2->as_VMReg()->next()); 1.79 +reg_def R_G2 ( NS, NS, Op_RegI, 2, G2->as_VMReg()); 1.80 +reg_def R_G3H(SOC, SOC, Op_RegI,131, G3->as_VMReg()->next()); 1.81 +reg_def R_G3 (SOC, SOC, Op_RegI, 3, G3->as_VMReg()); 1.82 +reg_def R_G4H(SOC, SOC, Op_RegI,132, G4->as_VMReg()->next()); 1.83 +reg_def R_G4 (SOC, SOC, Op_RegI, 4, G4->as_VMReg()); 1.84 +reg_def R_G5H(SOC, SOC, Op_RegI,133, G5->as_VMReg()->next()); 1.85 +reg_def R_G5 (SOC, SOC, Op_RegI, 5, G5->as_VMReg()); 1.86 +reg_def R_G6H( NS, NS, Op_RegI,134, G6->as_VMReg()->next()); 1.87 +reg_def R_G6 ( NS, NS, Op_RegI, 6, G6->as_VMReg()); 1.88 +reg_def R_G7H( NS, NS, Op_RegI,135, G7->as_VMReg()->next()); 1.89 +reg_def R_G7 ( NS, NS, Op_RegI, 7, G7->as_VMReg()); 1.90 + 1.91 +// Output Registers 0-7 1.92 +reg_def R_O0H(SOC, SOC, Op_RegI,136, O0->as_VMReg()->next()); 1.93 +reg_def R_O0 (SOC, SOC, Op_RegI, 8, O0->as_VMReg()); 1.94 +reg_def R_O1H(SOC, SOC, Op_RegI,137, O1->as_VMReg()->next()); 1.95 +reg_def R_O1 (SOC, SOC, Op_RegI, 9, O1->as_VMReg()); 1.96 +reg_def R_O2H(SOC, SOC, Op_RegI,138, O2->as_VMReg()->next()); 1.97 +reg_def R_O2 (SOC, SOC, Op_RegI, 10, O2->as_VMReg()); 1.98 +reg_def R_O3H(SOC, SOC, Op_RegI,139, O3->as_VMReg()->next()); 1.99 +reg_def R_O3 (SOC, SOC, Op_RegI, 11, O3->as_VMReg()); 1.100 +reg_def R_O4H(SOC, SOC, Op_RegI,140, O4->as_VMReg()->next()); 1.101 +reg_def R_O4 (SOC, SOC, Op_RegI, 12, O4->as_VMReg()); 1.102 +reg_def R_O5H(SOC, SOC, Op_RegI,141, O5->as_VMReg()->next()); 1.103 +reg_def R_O5 (SOC, SOC, Op_RegI, 13, O5->as_VMReg()); 1.104 +reg_def R_SPH( NS, NS, Op_RegI,142, SP->as_VMReg()->next()); 1.105 +reg_def R_SP ( NS, NS, Op_RegI, 14, SP->as_VMReg()); 1.106 +reg_def R_O7H(SOC, SOC, Op_RegI,143, O7->as_VMReg()->next()); 1.107 +reg_def R_O7 (SOC, SOC, Op_RegI, 15, O7->as_VMReg()); 1.108 + 1.109 +// Local Registers 0-7 1.110 +reg_def R_L0H( NS, NS, Op_RegI,144, L0->as_VMReg()->next()); 1.111 +reg_def R_L0 ( NS, NS, Op_RegI, 16, L0->as_VMReg()); 1.112 +reg_def R_L1H( NS, NS, Op_RegI,145, L1->as_VMReg()->next()); 1.113 +reg_def R_L1 ( NS, NS, Op_RegI, 17, L1->as_VMReg()); 1.114 +reg_def R_L2H( NS, NS, Op_RegI,146, L2->as_VMReg()->next()); 1.115 +reg_def R_L2 ( NS, NS, Op_RegI, 18, L2->as_VMReg()); 1.116 +reg_def R_L3H( NS, NS, Op_RegI,147, L3->as_VMReg()->next()); 1.117 +reg_def R_L3 ( NS, NS, Op_RegI, 19, L3->as_VMReg()); 1.118 +reg_def R_L4H( NS, NS, Op_RegI,148, L4->as_VMReg()->next()); 1.119 +reg_def R_L4 ( NS, NS, Op_RegI, 20, L4->as_VMReg()); 1.120 +reg_def R_L5H( NS, NS, Op_RegI,149, L5->as_VMReg()->next()); 1.121 +reg_def R_L5 ( NS, NS, Op_RegI, 21, L5->as_VMReg()); 1.122 +reg_def R_L6H( NS, NS, Op_RegI,150, L6->as_VMReg()->next()); 1.123 +reg_def R_L6 ( NS, NS, Op_RegI, 22, L6->as_VMReg()); 1.124 +reg_def R_L7H( NS, NS, Op_RegI,151, L7->as_VMReg()->next()); 1.125 +reg_def R_L7 ( NS, NS, Op_RegI, 23, L7->as_VMReg()); 1.126 + 1.127 +// Input Registers 0-7 1.128 +reg_def R_I0H( NS, NS, Op_RegI,152, I0->as_VMReg()->next()); 1.129 +reg_def R_I0 ( NS, NS, Op_RegI, 24, I0->as_VMReg()); 1.130 +reg_def R_I1H( NS, NS, Op_RegI,153, I1->as_VMReg()->next()); 1.131 +reg_def R_I1 ( NS, NS, Op_RegI, 25, I1->as_VMReg()); 1.132 +reg_def R_I2H( NS, NS, Op_RegI,154, I2->as_VMReg()->next()); 1.133 +reg_def R_I2 ( NS, NS, Op_RegI, 26, I2->as_VMReg()); 1.134 +reg_def R_I3H( NS, NS, Op_RegI,155, I3->as_VMReg()->next()); 1.135 +reg_def R_I3 ( NS, NS, Op_RegI, 27, I3->as_VMReg()); 1.136 +reg_def R_I4H( NS, NS, Op_RegI,156, I4->as_VMReg()->next()); 1.137 +reg_def R_I4 ( NS, NS, Op_RegI, 28, I4->as_VMReg()); 1.138 +reg_def R_I5H( NS, NS, Op_RegI,157, I5->as_VMReg()->next()); 1.139 +reg_def R_I5 ( NS, NS, Op_RegI, 29, I5->as_VMReg()); 1.140 +reg_def R_FPH( NS, NS, Op_RegI,158, FP->as_VMReg()->next()); 1.141 +reg_def R_FP ( NS, NS, Op_RegI, 30, FP->as_VMReg()); 1.142 +reg_def R_I7H( NS, NS, Op_RegI,159, I7->as_VMReg()->next()); 1.143 +reg_def R_I7 ( NS, NS, Op_RegI, 31, I7->as_VMReg()); 1.144 + 1.145 +// ---------------------------- 1.146 +// Float/Double Registers 1.147 +// ---------------------------- 1.148 + 1.149 +// Float Registers 1.150 +reg_def R_F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()); 1.151 +reg_def R_F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()); 1.152 +reg_def R_F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()); 1.153 +reg_def R_F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()); 1.154 +reg_def R_F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()); 1.155 +reg_def R_F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()); 1.156 +reg_def R_F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()); 1.157 +reg_def R_F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()); 1.158 +reg_def R_F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()); 1.159 +reg_def R_F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()); 1.160 +reg_def R_F10( SOC, SOC, Op_RegF, 10, F10->as_VMReg()); 1.161 +reg_def R_F11( SOC, SOC, Op_RegF, 11, F11->as_VMReg()); 1.162 +reg_def R_F12( SOC, SOC, Op_RegF, 12, F12->as_VMReg()); 1.163 +reg_def R_F13( SOC, SOC, Op_RegF, 13, F13->as_VMReg()); 1.164 +reg_def R_F14( SOC, SOC, Op_RegF, 14, F14->as_VMReg()); 1.165 +reg_def R_F15( SOC, SOC, Op_RegF, 15, F15->as_VMReg()); 1.166 +reg_def R_F16( SOC, SOC, Op_RegF, 16, F16->as_VMReg()); 1.167 +reg_def R_F17( SOC, SOC, Op_RegF, 17, F17->as_VMReg()); 1.168 +reg_def R_F18( SOC, SOC, Op_RegF, 18, F18->as_VMReg()); 1.169 +reg_def R_F19( SOC, SOC, Op_RegF, 19, F19->as_VMReg()); 1.170 +reg_def R_F20( SOC, SOC, Op_RegF, 20, F20->as_VMReg()); 1.171 +reg_def R_F21( SOC, SOC, Op_RegF, 21, F21->as_VMReg()); 1.172 +reg_def R_F22( SOC, SOC, Op_RegF, 22, F22->as_VMReg()); 1.173 +reg_def R_F23( SOC, SOC, Op_RegF, 23, F23->as_VMReg()); 1.174 +reg_def R_F24( SOC, SOC, Op_RegF, 24, F24->as_VMReg()); 1.175 +reg_def R_F25( SOC, SOC, Op_RegF, 25, F25->as_VMReg()); 1.176 +reg_def R_F26( SOC, SOC, Op_RegF, 26, F26->as_VMReg()); 1.177 +reg_def R_F27( SOC, SOC, Op_RegF, 27, F27->as_VMReg()); 1.178 +reg_def R_F28( SOC, SOC, Op_RegF, 28, F28->as_VMReg()); 1.179 +reg_def R_F29( SOC, SOC, Op_RegF, 29, F29->as_VMReg()); 1.180 +reg_def R_F30( SOC, SOC, Op_RegF, 30, F30->as_VMReg()); 1.181 +reg_def R_F31( SOC, SOC, Op_RegF, 31, F31->as_VMReg()); 1.182 + 1.183 +// Double Registers 1.184 +// The rules of ADL require that double registers be defined in pairs. 1.185 +// Each pair must be two 32-bit values, but not necessarily a pair of 1.186 +// single float registers. In each pair, ADLC-assigned register numbers 1.187 +// must be adjacent, with the lower number even. Finally, when the 1.188 +// CPU stores such a register pair to memory, the word associated with 1.189 +// the lower ADLC-assigned number must be stored to the lower address. 1.190 + 1.191 +// These definitions specify the actual bit encodings of the sparc 1.192 +// double fp register numbers. FloatRegisterImpl in register_sparc.hpp 1.193 +// wants 0-63, so we have to convert every time we want to use fp regs 1.194 +// with the macroassembler, using reg_to_DoubleFloatRegister_object(). 1.195 +// 255 is a flag meaning 'dont go here'. 1.196 +// I believe we can't handle callee-save doubles D32 and up until 1.197 +// the place in the sparc stack crawler that asserts on the 255 is 1.198 +// fixed up. 1.199 +reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()); 1.200 +reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()->next()); 1.201 +reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()); 1.202 +reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()->next()); 1.203 +reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()); 1.204 +reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()->next()); 1.205 +reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()); 1.206 +reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()->next()); 1.207 +reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()); 1.208 +reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()->next()); 1.209 +reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()); 1.210 +reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()->next()); 1.211 +reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()); 1.212 +reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()->next()); 1.213 +reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()); 1.214 +reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()->next()); 1.215 +reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()); 1.216 +reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()->next()); 1.217 +reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()); 1.218 +reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()->next()); 1.219 +reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()); 1.220 +reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()->next()); 1.221 +reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()); 1.222 +reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()->next()); 1.223 +reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()); 1.224 +reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()->next()); 1.225 +reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()); 1.226 +reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()->next()); 1.227 +reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()); 1.228 +reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()->next()); 1.229 +reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()); 1.230 +reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()->next()); 1.231 + 1.232 + 1.233 +// ---------------------------- 1.234 +// Special Registers 1.235 +// Condition Codes Flag Registers 1.236 +// I tried to break out ICC and XCC but it's not very pretty. 1.237 +// Every Sparc instruction which defs/kills one also kills the other. 1.238 +// Hence every compare instruction which defs one kind of flags ends 1.239 +// up needing a kill of the other. 1.240 +reg_def CCR (SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad()); 1.241 + 1.242 +reg_def FCC0(SOC, SOC, Op_RegFlags, 0, VMRegImpl::Bad()); 1.243 +reg_def FCC1(SOC, SOC, Op_RegFlags, 1, VMRegImpl::Bad()); 1.244 +reg_def FCC2(SOC, SOC, Op_RegFlags, 2, VMRegImpl::Bad()); 1.245 +reg_def FCC3(SOC, SOC, Op_RegFlags, 3, VMRegImpl::Bad()); 1.246 + 1.247 +// ---------------------------- 1.248 +// Specify the enum values for the registers. These enums are only used by the 1.249 +// OptoReg "class". We can convert these enum values at will to VMReg when needed 1.250 +// for visibility to the rest of the vm. The order of this enum influences the 1.251 +// register allocator so having the freedom to set this order and not be stuck 1.252 +// with the order that is natural for the rest of the vm is worth it. 1.253 +alloc_class chunk0( 1.254 + R_L0,R_L0H, R_L1,R_L1H, R_L2,R_L2H, R_L3,R_L3H, R_L4,R_L4H, R_L5,R_L5H, R_L6,R_L6H, R_L7,R_L7H, 1.255 + R_G0,R_G0H, R_G1,R_G1H, R_G2,R_G2H, R_G3,R_G3H, R_G4,R_G4H, R_G5,R_G5H, R_G6,R_G6H, R_G7,R_G7H, 1.256 + R_O7,R_O7H, R_SP,R_SPH, R_O0,R_O0H, R_O1,R_O1H, R_O2,R_O2H, R_O3,R_O3H, R_O4,R_O4H, R_O5,R_O5H, 1.257 + R_I0,R_I0H, R_I1,R_I1H, R_I2,R_I2H, R_I3,R_I3H, R_I4,R_I4H, R_I5,R_I5H, R_FP,R_FPH, R_I7,R_I7H); 1.258 + 1.259 +// Note that a register is not allocatable unless it is also mentioned 1.260 +// in a widely-used reg_class below. Thus, R_G7 and R_G0 are outside i_reg. 1.261 + 1.262 +alloc_class chunk1( 1.263 + // The first registers listed here are those most likely to be used 1.264 + // as temporaries. We move F0..F7 away from the front of the list, 1.265 + // to reduce the likelihood of interferences with parameters and 1.266 + // return values. Likewise, we avoid using F0/F1 for parameters, 1.267 + // since they are used for return values. 1.268 + // This FPU fine-tuning is worth about 1% on the SPEC geomean. 1.269 + R_F8 ,R_F9 ,R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, 1.270 + R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23, 1.271 + R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31, 1.272 + R_F0 ,R_F1 ,R_F2 ,R_F3 ,R_F4 ,R_F5 ,R_F6 ,R_F7 , // used for arguments and return values 1.273 + R_D32,R_D32x,R_D34,R_D34x,R_D36,R_D36x,R_D38,R_D38x, 1.274 + R_D40,R_D40x,R_D42,R_D42x,R_D44,R_D44x,R_D46,R_D46x, 1.275 + R_D48,R_D48x,R_D50,R_D50x,R_D52,R_D52x,R_D54,R_D54x, 1.276 + R_D56,R_D56x,R_D58,R_D58x,R_D60,R_D60x,R_D62,R_D62x); 1.277 + 1.278 +alloc_class chunk2(CCR, FCC0, FCC1, FCC2, FCC3); 1.279 + 1.280 +//----------Architecture Description Register Classes-------------------------- 1.281 +// Several register classes are automatically defined based upon information in 1.282 +// this architecture description. 1.283 +// 1) reg_class inline_cache_reg ( as defined in frame section ) 1.284 +// 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 1.285 +// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 1.286 +// 1.287 + 1.288 +// G0 is not included in integer class since it has special meaning. 1.289 +reg_class g0_reg(R_G0); 1.290 + 1.291 +// ---------------------------- 1.292 +// Integer Register Classes 1.293 +// ---------------------------- 1.294 +// Exclusions from i_reg: 1.295 +// R_G0: hardwired zero 1.296 +// R_G2: reserved by HotSpot to the TLS register (invariant within Java) 1.297 +// R_G6: reserved by Solaris ABI to tools 1.298 +// R_G7: reserved by Solaris ABI to libthread 1.299 +// R_O7: Used as a temp in many encodings 1.300 +reg_class int_reg(R_G1,R_G3,R_G4,R_G5,R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); 1.301 + 1.302 +// Class for all integer registers, except the G registers. This is used for 1.303 +// encodings which use G registers as temps. The regular inputs to such 1.304 +// instructions use a "notemp_" prefix, as a hack to ensure that the allocator 1.305 +// will not put an input into a temp register. 1.306 +reg_class notemp_int_reg(R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); 1.307 + 1.308 +reg_class g1_regI(R_G1); 1.309 +reg_class g3_regI(R_G3); 1.310 +reg_class g4_regI(R_G4); 1.311 +reg_class o0_regI(R_O0); 1.312 +reg_class o7_regI(R_O7); 1.313 + 1.314 +// ---------------------------- 1.315 +// Pointer Register Classes 1.316 +// ---------------------------- 1.317 +#ifdef _LP64 1.318 +// 64-bit build means 64-bit pointers means hi/lo pairs 1.319 +reg_class ptr_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5, 1.320 + R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, 1.321 + R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, 1.322 + R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 ); 1.323 +// Lock encodings use G3 and G4 internally 1.324 +reg_class lock_ptr_reg( R_G1H,R_G1, R_G5H,R_G5, 1.325 + R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, 1.326 + R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, 1.327 + R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 ); 1.328 +// Special class for storeP instructions, which can store SP or RPC to TLS. 1.329 +// It is also used for memory addressing, allowing direct TLS addressing. 1.330 +reg_class sp_ptr_reg( R_G1H,R_G1, R_G2H,R_G2, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5, 1.331 + R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5, R_SPH,R_SP, 1.332 + R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7, 1.333 + R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5, R_FPH,R_FP ); 1.334 +// R_L7 is the lowest-priority callee-save (i.e., NS) register 1.335 +// We use it to save R_G2 across calls out of Java. 1.336 +reg_class l7_regP(R_L7H,R_L7); 1.337 + 1.338 +// Other special pointer regs 1.339 +reg_class g1_regP(R_G1H,R_G1); 1.340 +reg_class g2_regP(R_G2H,R_G2); 1.341 +reg_class g3_regP(R_G3H,R_G3); 1.342 +reg_class g4_regP(R_G4H,R_G4); 1.343 +reg_class g5_regP(R_G5H,R_G5); 1.344 +reg_class i0_regP(R_I0H,R_I0); 1.345 +reg_class o0_regP(R_O0H,R_O0); 1.346 +reg_class o1_regP(R_O1H,R_O1); 1.347 +reg_class o2_regP(R_O2H,R_O2); 1.348 +reg_class o7_regP(R_O7H,R_O7); 1.349 + 1.350 +#else // _LP64 1.351 +// 32-bit build means 32-bit pointers means 1 register. 1.352 +reg_class ptr_reg( R_G1, R_G3,R_G4,R_G5, 1.353 + R_O0,R_O1,R_O2,R_O3,R_O4,R_O5, 1.354 + R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, 1.355 + R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); 1.356 +// Lock encodings use G3 and G4 internally 1.357 +reg_class lock_ptr_reg(R_G1, R_G5, 1.358 + R_O0,R_O1,R_O2,R_O3,R_O4,R_O5, 1.359 + R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, 1.360 + R_I0,R_I1,R_I2,R_I3,R_I4,R_I5); 1.361 +// Special class for storeP instructions, which can store SP or RPC to TLS. 1.362 +// It is also used for memory addressing, allowing direct TLS addressing. 1.363 +reg_class sp_ptr_reg( R_G1,R_G2,R_G3,R_G4,R_G5, 1.364 + R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_SP, 1.365 + R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7, 1.366 + R_I0,R_I1,R_I2,R_I3,R_I4,R_I5,R_FP); 1.367 +// R_L7 is the lowest-priority callee-save (i.e., NS) register 1.368 +// We use it to save R_G2 across calls out of Java. 1.369 +reg_class l7_regP(R_L7); 1.370 + 1.371 +// Other special pointer regs 1.372 +reg_class g1_regP(R_G1); 1.373 +reg_class g2_regP(R_G2); 1.374 +reg_class g3_regP(R_G3); 1.375 +reg_class g4_regP(R_G4); 1.376 +reg_class g5_regP(R_G5); 1.377 +reg_class i0_regP(R_I0); 1.378 +reg_class o0_regP(R_O0); 1.379 +reg_class o1_regP(R_O1); 1.380 +reg_class o2_regP(R_O2); 1.381 +reg_class o7_regP(R_O7); 1.382 +#endif // _LP64 1.383 + 1.384 + 1.385 +// ---------------------------- 1.386 +// Long Register Classes 1.387 +// ---------------------------- 1.388 +// Longs in 1 register. Aligned adjacent hi/lo pairs. 1.389 +// Note: O7 is never in this class; it is sometimes used as an encoding temp. 1.390 +reg_class long_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5 1.391 + ,R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5 1.392 +#ifdef _LP64 1.393 +// 64-bit, longs in 1 register: use all 64-bit integer registers 1.394 +// 32-bit, longs in 1 register: cannot use I's and L's. Restrict to O's and G's. 1.395 + ,R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7 1.396 + ,R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 1.397 +#endif // _LP64 1.398 + ); 1.399 + 1.400 +reg_class g1_regL(R_G1H,R_G1); 1.401 +reg_class o2_regL(R_O2H,R_O2); 1.402 +reg_class o7_regL(R_O7H,R_O7); 1.403 + 1.404 +// ---------------------------- 1.405 +// Special Class for Condition Code Flags Register 1.406 +reg_class int_flags(CCR); 1.407 +reg_class float_flags(FCC0,FCC1,FCC2,FCC3); 1.408 +reg_class float_flag0(FCC0); 1.409 + 1.410 + 1.411 +// ---------------------------- 1.412 +// Float Point Register Classes 1.413 +// ---------------------------- 1.414 +// Skip F30/F31, they are reserved for mem-mem copies 1.415 +reg_class sflt_reg(R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29); 1.416 + 1.417 +// Paired floating point registers--they show up in the same order as the floats, 1.418 +// but they are used with the "Op_RegD" type, and always occur in even/odd pairs. 1.419 +reg_class dflt_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, 1.420 + R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29, 1.421 + /* Use extra V9 double registers; this AD file does not support V8 */ 1.422 + R_D32,R_D32x,R_D34,R_D34x,R_D36,R_D36x,R_D38,R_D38x,R_D40,R_D40x,R_D42,R_D42x,R_D44,R_D44x,R_D46,R_D46x, 1.423 + R_D48,R_D48x,R_D50,R_D50x,R_D52,R_D52x,R_D54,R_D54x,R_D56,R_D56x,R_D58,R_D58x,R_D60,R_D60x,R_D62,R_D62x 1.424 + ); 1.425 + 1.426 +// Paired floating point registers--they show up in the same order as the floats, 1.427 +// but they are used with the "Op_RegD" type, and always occur in even/odd pairs. 1.428 +// This class is usable for mis-aligned loads as happen in I2C adapters. 1.429 +reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, 1.430 + R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31 ); 1.431 +%} 1.432 + 1.433 +//----------DEFINITION BLOCK--------------------------------------------------- 1.434 +// Define name --> value mappings to inform the ADLC of an integer valued name 1.435 +// Current support includes integer values in the range [0, 0x7FFFFFFF] 1.436 +// Format: 1.437 +// int_def <name> ( <int_value>, <expression>); 1.438 +// Generated Code in ad_<arch>.hpp 1.439 +// #define <name> (<expression>) 1.440 +// // value == <int_value> 1.441 +// Generated code in ad_<arch>.cpp adlc_verification() 1.442 +// assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 1.443 +// 1.444 +definitions %{ 1.445 +// The default cost (of an ALU instruction). 1.446 + int_def DEFAULT_COST ( 100, 100); 1.447 + int_def HUGE_COST (1000000, 1000000); 1.448 + 1.449 +// Memory refs are twice as expensive as run-of-the-mill. 1.450 + int_def MEMORY_REF_COST ( 200, DEFAULT_COST * 2); 1.451 + 1.452 +// Branches are even more expensive. 1.453 + int_def BRANCH_COST ( 300, DEFAULT_COST * 3); 1.454 + int_def CALL_COST ( 300, DEFAULT_COST * 3); 1.455 +%} 1.456 + 1.457 + 1.458 +//----------SOURCE BLOCK------------------------------------------------------- 1.459 +// This is a block of C++ code which provides values, functions, and 1.460 +// definitions necessary in the rest of the architecture description 1.461 +source_hpp %{ 1.462 +// Must be visible to the DFA in dfa_sparc.cpp 1.463 +extern bool can_branch_register( Node *bol, Node *cmp ); 1.464 + 1.465 +// Macros to extract hi & lo halves from a long pair. 1.466 +// G0 is not part of any long pair, so assert on that. 1.467 +// Prevents accidently using G1 instead of G0. 1.468 +#define LONG_HI_REG(x) (x) 1.469 +#define LONG_LO_REG(x) (x) 1.470 + 1.471 +%} 1.472 + 1.473 +source %{ 1.474 +#define __ _masm. 1.475 + 1.476 +// tertiary op of a LoadP or StoreP encoding 1.477 +#define REGP_OP true 1.478 + 1.479 +static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding); 1.480 +static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding); 1.481 +static Register reg_to_register_object(int register_encoding); 1.482 + 1.483 +// Used by the DFA in dfa_sparc.cpp. 1.484 +// Check for being able to use a V9 branch-on-register. Requires a 1.485 +// compare-vs-zero, equal/not-equal, of a value which was zero- or sign- 1.486 +// extended. Doesn't work following an integer ADD, for example, because of 1.487 +// overflow (-1 incremented yields 0 plus a carry in the high-order word). On 1.488 +// 32-bit V9 systems, interrupts currently blow away the high-order 32 bits and 1.489 +// replace them with zero, which could become sign-extension in a different OS 1.490 +// release. There's no obvious reason why an interrupt will ever fill these 1.491 +// bits with non-zero junk (the registers are reloaded with standard LD 1.492 +// instructions which either zero-fill or sign-fill). 1.493 +bool can_branch_register( Node *bol, Node *cmp ) { 1.494 + if( !BranchOnRegister ) return false; 1.495 +#ifdef _LP64 1.496 + if( cmp->Opcode() == Op_CmpP ) 1.497 + return true; // No problems with pointer compares 1.498 +#endif 1.499 + if( cmp->Opcode() == Op_CmpL ) 1.500 + return true; // No problems with long compares 1.501 + 1.502 + if( !SparcV9RegsHiBitsZero ) return false; 1.503 + if( bol->as_Bool()->_test._test != BoolTest::ne && 1.504 + bol->as_Bool()->_test._test != BoolTest::eq ) 1.505 + return false; 1.506 + 1.507 + // Check for comparing against a 'safe' value. Any operation which 1.508 + // clears out the high word is safe. Thus, loads and certain shifts 1.509 + // are safe, as are non-negative constants. Any operation which 1.510 + // preserves zero bits in the high word is safe as long as each of its 1.511 + // inputs are safe. Thus, phis and bitwise booleans are safe if their 1.512 + // inputs are safe. At present, the only important case to recognize 1.513 + // seems to be loads. Constants should fold away, and shifts & 1.514 + // logicals can use the 'cc' forms. 1.515 + Node *x = cmp->in(1); 1.516 + if( x->is_Load() ) return true; 1.517 + if( x->is_Phi() ) { 1.518 + for( uint i = 1; i < x->req(); i++ ) 1.519 + if( !x->in(i)->is_Load() ) 1.520 + return false; 1.521 + return true; 1.522 + } 1.523 + return false; 1.524 +} 1.525 + 1.526 +// **************************************************************************** 1.527 + 1.528 +// REQUIRED FUNCTIONALITY 1.529 + 1.530 +// !!!!! Special hack to get all type of calls to specify the byte offset 1.531 +// from the start of the call to the point where the return address 1.532 +// will point. 1.533 +// The "return address" is the address of the call instruction, plus 8. 1.534 + 1.535 +int MachCallStaticJavaNode::ret_addr_offset() { 1.536 + return NativeCall::instruction_size; // call; delay slot 1.537 +} 1.538 + 1.539 +int MachCallDynamicJavaNode::ret_addr_offset() { 1.540 + int vtable_index = this->_vtable_index; 1.541 + if (vtable_index < 0) { 1.542 + // must be invalid_vtable_index, not nonvirtual_vtable_index 1.543 + assert(vtable_index == methodOopDesc::invalid_vtable_index, "correct sentinel value"); 1.544 + return (NativeMovConstReg::instruction_size + 1.545 + NativeCall::instruction_size); // sethi; setlo; call; delay slot 1.546 + } else { 1.547 + assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1.548 + int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); 1.549 + int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); 1.550 + if( Assembler::is_simm13(v_off) ) { 1.551 + return (3*BytesPerInstWord + // ld_ptr, ld_ptr, ld_ptr 1.552 + NativeCall::instruction_size); // call; delay slot 1.553 + } else { 1.554 + return (5*BytesPerInstWord + // ld_ptr, set_hi, set, ld_ptr, ld_ptr 1.555 + NativeCall::instruction_size); // call; delay slot 1.556 + } 1.557 + } 1.558 +} 1.559 + 1.560 +int MachCallRuntimeNode::ret_addr_offset() { 1.561 +#ifdef _LP64 1.562 + return NativeFarCall::instruction_size; // farcall; delay slot 1.563 +#else 1.564 + return NativeCall::instruction_size; // call; delay slot 1.565 +#endif 1.566 +} 1.567 + 1.568 +// Indicate if the safepoint node needs the polling page as an input. 1.569 +// Since Sparc does not have absolute addressing, it does. 1.570 +bool SafePointNode::needs_polling_address_input() { 1.571 + return true; 1.572 +} 1.573 + 1.574 +// emit an interrupt that is caught by the debugger (for debugging compiler) 1.575 +void emit_break(CodeBuffer &cbuf) { 1.576 + MacroAssembler _masm(&cbuf); 1.577 + __ breakpoint_trap(); 1.578 +} 1.579 + 1.580 +#ifndef PRODUCT 1.581 +void MachBreakpointNode::format( PhaseRegAlloc *, outputStream *st ) const { 1.582 + st->print("TA"); 1.583 +} 1.584 +#endif 1.585 + 1.586 +void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.587 + emit_break(cbuf); 1.588 +} 1.589 + 1.590 +uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1.591 + return MachNode::size(ra_); 1.592 +} 1.593 + 1.594 +// Traceable jump 1.595 +void emit_jmpl(CodeBuffer &cbuf, int jump_target) { 1.596 + MacroAssembler _masm(&cbuf); 1.597 + Register rdest = reg_to_register_object(jump_target); 1.598 + __ JMP(rdest, 0); 1.599 + __ delayed()->nop(); 1.600 +} 1.601 + 1.602 +// Traceable jump and set exception pc 1.603 +void emit_jmpl_set_exception_pc(CodeBuffer &cbuf, int jump_target) { 1.604 + MacroAssembler _masm(&cbuf); 1.605 + Register rdest = reg_to_register_object(jump_target); 1.606 + __ JMP(rdest, 0); 1.607 + __ delayed()->add(O7, frame::pc_return_offset, Oissuing_pc ); 1.608 +} 1.609 + 1.610 +void emit_nop(CodeBuffer &cbuf) { 1.611 + MacroAssembler _masm(&cbuf); 1.612 + __ nop(); 1.613 +} 1.614 + 1.615 +void emit_illtrap(CodeBuffer &cbuf) { 1.616 + MacroAssembler _masm(&cbuf); 1.617 + __ illtrap(0); 1.618 +} 1.619 + 1.620 + 1.621 +intptr_t get_offset_from_base(const MachNode* n, const TypePtr* atype, int disp32) { 1.622 + assert(n->rule() != loadUB_rule, ""); 1.623 + 1.624 + intptr_t offset = 0; 1.625 + const TypePtr *adr_type = TYPE_PTR_SENTINAL; // Check for base==RegI, disp==immP 1.626 + const Node* addr = n->get_base_and_disp(offset, adr_type); 1.627 + assert(adr_type == (const TypePtr*)-1, "VerifyOops: no support for sparc operands with base==RegI, disp==immP"); 1.628 + assert(addr != NULL && addr != (Node*)-1, "invalid addr"); 1.629 + assert(addr->bottom_type()->isa_oopptr() == atype, ""); 1.630 + atype = atype->add_offset(offset); 1.631 + assert(disp32 == offset, "wrong disp32"); 1.632 + return atype->_offset; 1.633 +} 1.634 + 1.635 + 1.636 +intptr_t get_offset_from_base_2(const MachNode* n, const TypePtr* atype, int disp32) { 1.637 + assert(n->rule() != loadUB_rule, ""); 1.638 + 1.639 + intptr_t offset = 0; 1.640 + Node* addr = n->in(2); 1.641 + assert(addr->bottom_type()->isa_oopptr() == atype, ""); 1.642 + if (addr->is_Mach() && addr->as_Mach()->ideal_Opcode() == Op_AddP) { 1.643 + Node* a = addr->in(2/*AddPNode::Address*/); 1.644 + Node* o = addr->in(3/*AddPNode::Offset*/); 1.645 + offset = o->is_Con() ? o->bottom_type()->is_intptr_t()->get_con() : Type::OffsetBot; 1.646 + atype = a->bottom_type()->is_ptr()->add_offset(offset); 1.647 + assert(atype->isa_oop_ptr(), "still an oop"); 1.648 + } 1.649 + offset = atype->is_ptr()->_offset; 1.650 + if (offset != Type::OffsetBot) offset += disp32; 1.651 + return offset; 1.652 +} 1.653 + 1.654 +// Standard Sparc opcode form2 field breakdown 1.655 +static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) { 1.656 + f0 &= (1<<19)-1; // Mask displacement to 19 bits 1.657 + int op = (f30 << 30) | 1.658 + (f29 << 29) | 1.659 + (f25 << 25) | 1.660 + (f22 << 22) | 1.661 + (f20 << 20) | 1.662 + (f19 << 19) | 1.663 + (f0 << 0); 1.664 + *((int*)(cbuf.code_end())) = op; 1.665 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.666 +} 1.667 + 1.668 +// Standard Sparc opcode form2 field breakdown 1.669 +static inline void emit2_22(CodeBuffer &cbuf, int f30, int f25, int f22, int f0 ) { 1.670 + f0 >>= 10; // Drop 10 bits 1.671 + f0 &= (1<<22)-1; // Mask displacement to 22 bits 1.672 + int op = (f30 << 30) | 1.673 + (f25 << 25) | 1.674 + (f22 << 22) | 1.675 + (f0 << 0); 1.676 + *((int*)(cbuf.code_end())) = op; 1.677 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.678 +} 1.679 + 1.680 +// Standard Sparc opcode form3 field breakdown 1.681 +static inline void emit3(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int f5, int f0 ) { 1.682 + int op = (f30 << 30) | 1.683 + (f25 << 25) | 1.684 + (f19 << 19) | 1.685 + (f14 << 14) | 1.686 + (f5 << 5) | 1.687 + (f0 << 0); 1.688 + *((int*)(cbuf.code_end())) = op; 1.689 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.690 +} 1.691 + 1.692 +// Standard Sparc opcode form3 field breakdown 1.693 +static inline void emit3_simm13(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm13 ) { 1.694 + simm13 &= (1<<13)-1; // Mask to 13 bits 1.695 + int op = (f30 << 30) | 1.696 + (f25 << 25) | 1.697 + (f19 << 19) | 1.698 + (f14 << 14) | 1.699 + (1 << 13) | // bit to indicate immediate-mode 1.700 + (simm13<<0); 1.701 + *((int*)(cbuf.code_end())) = op; 1.702 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.703 +} 1.704 + 1.705 +static inline void emit3_simm10(CodeBuffer &cbuf, int f30, int f25, int f19, int f14, int simm10 ) { 1.706 + simm10 &= (1<<10)-1; // Mask to 10 bits 1.707 + emit3_simm13(cbuf,f30,f25,f19,f14,simm10); 1.708 +} 1.709 + 1.710 +#ifdef ASSERT 1.711 +// Helper function for VerifyOops in emit_form3_mem_reg 1.712 +void verify_oops_warning(const MachNode *n, int ideal_op, int mem_op) { 1.713 + warning("VerifyOops encountered unexpected instruction:"); 1.714 + n->dump(2); 1.715 + warning("Instruction has ideal_Opcode==Op_%s and op_ld==Op_%s \n", NodeClassNames[ideal_op], NodeClassNames[mem_op]); 1.716 +} 1.717 +#endif 1.718 + 1.719 + 1.720 +void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int tertiary, 1.721 + int src1_enc, int disp32, int src2_enc, int dst_enc) { 1.722 + 1.723 +#ifdef ASSERT 1.724 + // The following code implements the +VerifyOops feature. 1.725 + // It verifies oop values which are loaded into or stored out of 1.726 + // the current method activation. +VerifyOops complements techniques 1.727 + // like ScavengeALot, because it eagerly inspects oops in transit, 1.728 + // as they enter or leave the stack, as opposed to ScavengeALot, 1.729 + // which inspects oops "at rest", in the stack or heap, at safepoints. 1.730 + // For this reason, +VerifyOops can sometimes detect bugs very close 1.731 + // to their point of creation. It can also serve as a cross-check 1.732 + // on the validity of oop maps, when used toegether with ScavengeALot. 1.733 + 1.734 + // It would be good to verify oops at other points, especially 1.735 + // when an oop is used as a base pointer for a load or store. 1.736 + // This is presently difficult, because it is hard to know when 1.737 + // a base address is biased or not. (If we had such information, 1.738 + // it would be easy and useful to make a two-argument version of 1.739 + // verify_oop which unbiases the base, and performs verification.) 1.740 + 1.741 + assert((uint)tertiary == 0xFFFFFFFF || tertiary == REGP_OP, "valid tertiary"); 1.742 + bool is_verified_oop_base = false; 1.743 + bool is_verified_oop_load = false; 1.744 + bool is_verified_oop_store = false; 1.745 + int tmp_enc = -1; 1.746 + if (VerifyOops && src1_enc != R_SP_enc) { 1.747 + // classify the op, mainly for an assert check 1.748 + int st_op = 0, ld_op = 0; 1.749 + switch (primary) { 1.750 + case Assembler::stb_op3: st_op = Op_StoreB; break; 1.751 + case Assembler::sth_op3: st_op = Op_StoreC; break; 1.752 + case Assembler::stx_op3: // may become StoreP or stay StoreI or StoreD0 1.753 + case Assembler::stw_op3: st_op = Op_StoreI; break; 1.754 + case Assembler::std_op3: st_op = Op_StoreL; break; 1.755 + case Assembler::stf_op3: st_op = Op_StoreF; break; 1.756 + case Assembler::stdf_op3: st_op = Op_StoreD; break; 1.757 + 1.758 + case Assembler::ldsb_op3: ld_op = Op_LoadB; break; 1.759 + case Assembler::lduh_op3: ld_op = Op_LoadC; break; 1.760 + case Assembler::ldsh_op3: ld_op = Op_LoadS; break; 1.761 + case Assembler::ldx_op3: // may become LoadP or stay LoadI 1.762 + case Assembler::ldsw_op3: // may become LoadP or stay LoadI 1.763 + case Assembler::lduw_op3: ld_op = Op_LoadI; break; 1.764 + case Assembler::ldd_op3: ld_op = Op_LoadL; break; 1.765 + case Assembler::ldf_op3: ld_op = Op_LoadF; break; 1.766 + case Assembler::lddf_op3: ld_op = Op_LoadD; break; 1.767 + case Assembler::ldub_op3: ld_op = Op_LoadB; break; 1.768 + case Assembler::prefetch_op3: ld_op = Op_LoadI; break; 1.769 + 1.770 + default: ShouldNotReachHere(); 1.771 + } 1.772 + if (tertiary == REGP_OP) { 1.773 + if (st_op == Op_StoreI) st_op = Op_StoreP; 1.774 + else if (ld_op == Op_LoadI) ld_op = Op_LoadP; 1.775 + else ShouldNotReachHere(); 1.776 + if (st_op) { 1.777 + // a store 1.778 + // inputs are (0:control, 1:memory, 2:address, 3:value) 1.779 + Node* n2 = n->in(3); 1.780 + if (n2 != NULL) { 1.781 + const Type* t = n2->bottom_type(); 1.782 + is_verified_oop_store = t->isa_oop_ptr() ? (t->is_ptr()->_offset==0) : false; 1.783 + } 1.784 + } else { 1.785 + // a load 1.786 + const Type* t = n->bottom_type(); 1.787 + is_verified_oop_load = t->isa_oop_ptr() ? (t->is_ptr()->_offset==0) : false; 1.788 + } 1.789 + } 1.790 + 1.791 + if (ld_op) { 1.792 + // a Load 1.793 + // inputs are (0:control, 1:memory, 2:address) 1.794 + if (!(n->ideal_Opcode()==ld_op) && // Following are special cases 1.795 + !(n->ideal_Opcode()==Op_LoadLLocked && ld_op==Op_LoadI) && 1.796 + !(n->ideal_Opcode()==Op_LoadPLocked && ld_op==Op_LoadP) && 1.797 + !(n->ideal_Opcode()==Op_LoadI && ld_op==Op_LoadF) && 1.798 + !(n->ideal_Opcode()==Op_LoadF && ld_op==Op_LoadI) && 1.799 + !(n->ideal_Opcode()==Op_LoadRange && ld_op==Op_LoadI) && 1.800 + !(n->ideal_Opcode()==Op_LoadKlass && ld_op==Op_LoadP) && 1.801 + !(n->ideal_Opcode()==Op_LoadL && ld_op==Op_LoadI) && 1.802 + !(n->ideal_Opcode()==Op_LoadL_unaligned && ld_op==Op_LoadI) && 1.803 + !(n->ideal_Opcode()==Op_LoadD_unaligned && ld_op==Op_LoadF) && 1.804 + !(n->ideal_Opcode()==Op_ConvI2F && ld_op==Op_LoadF) && 1.805 + !(n->ideal_Opcode()==Op_ConvI2D && ld_op==Op_LoadF) && 1.806 + !(n->ideal_Opcode()==Op_PrefetchRead && ld_op==Op_LoadI) && 1.807 + !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) && 1.808 + !(n->rule() == loadUB_rule)) { 1.809 + verify_oops_warning(n, n->ideal_Opcode(), ld_op); 1.810 + } 1.811 + } else if (st_op) { 1.812 + // a Store 1.813 + // inputs are (0:control, 1:memory, 2:address, 3:value) 1.814 + if (!(n->ideal_Opcode()==st_op) && // Following are special cases 1.815 + !(n->ideal_Opcode()==Op_StoreCM && st_op==Op_StoreB) && 1.816 + !(n->ideal_Opcode()==Op_StoreI && st_op==Op_StoreF) && 1.817 + !(n->ideal_Opcode()==Op_StoreF && st_op==Op_StoreI) && 1.818 + !(n->ideal_Opcode()==Op_StoreL && st_op==Op_StoreI) && 1.819 + !(n->ideal_Opcode()==Op_StoreD && st_op==Op_StoreI && n->rule() == storeD0_rule)) { 1.820 + verify_oops_warning(n, n->ideal_Opcode(), st_op); 1.821 + } 1.822 + } 1.823 + 1.824 + if (src2_enc == R_G0_enc && n->rule() != loadUB_rule && n->ideal_Opcode() != Op_StoreCM ) { 1.825 + Node* addr = n->in(2); 1.826 + if (!(addr->is_Mach() && addr->as_Mach()->ideal_Opcode() == Op_AddP)) { 1.827 + const TypeOopPtr* atype = addr->bottom_type()->isa_instptr(); // %%% oopptr? 1.828 + if (atype != NULL) { 1.829 + intptr_t offset = get_offset_from_base(n, atype, disp32); 1.830 + intptr_t offset_2 = get_offset_from_base_2(n, atype, disp32); 1.831 + if (offset != offset_2) { 1.832 + get_offset_from_base(n, atype, disp32); 1.833 + get_offset_from_base_2(n, atype, disp32); 1.834 + } 1.835 + assert(offset == offset_2, "different offsets"); 1.836 + if (offset == disp32) { 1.837 + // we now know that src1 is a true oop pointer 1.838 + is_verified_oop_base = true; 1.839 + if (ld_op && src1_enc == dst_enc && ld_op != Op_LoadF && ld_op != Op_LoadD) { 1.840 + if( primary == Assembler::ldd_op3 ) { 1.841 + is_verified_oop_base = false; // Cannot 'ldd' into O7 1.842 + } else { 1.843 + tmp_enc = dst_enc; 1.844 + dst_enc = R_O7_enc; // Load into O7; preserve source oop 1.845 + assert(src1_enc != dst_enc, ""); 1.846 + } 1.847 + } 1.848 + } 1.849 + if (st_op && (( offset == oopDesc::klass_offset_in_bytes()) 1.850 + || offset == oopDesc::mark_offset_in_bytes())) { 1.851 + // loading the mark should not be allowed either, but 1.852 + // we don't check this since it conflicts with InlineObjectHash 1.853 + // usage of LoadINode to get the mark. We could keep the 1.854 + // check if we create a new LoadMarkNode 1.855 + // but do not verify the object before its header is initialized 1.856 + ShouldNotReachHere(); 1.857 + } 1.858 + } 1.859 + } 1.860 + } 1.861 + } 1.862 +#endif 1.863 + 1.864 + uint instr; 1.865 + instr = (Assembler::ldst_op << 30) 1.866 + | (dst_enc << 25) 1.867 + | (primary << 19) 1.868 + | (src1_enc << 14); 1.869 + 1.870 + uint index = src2_enc; 1.871 + int disp = disp32; 1.872 + 1.873 + if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) 1.874 + disp += STACK_BIAS; 1.875 + 1.876 + // We should have a compiler bailout here rather than a guarantee. 1.877 + // Better yet would be some mechanism to handle variable-size matches correctly. 1.878 + guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" ); 1.879 + 1.880 + if( disp == 0 ) { 1.881 + // use reg-reg form 1.882 + // bit 13 is already zero 1.883 + instr |= index; 1.884 + } else { 1.885 + // use reg-imm form 1.886 + instr |= 0x00002000; // set bit 13 to one 1.887 + instr |= disp & 0x1FFF; 1.888 + } 1.889 + 1.890 + uint *code = (uint*)cbuf.code_end(); 1.891 + *code = instr; 1.892 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.893 + 1.894 +#ifdef ASSERT 1.895 + { 1.896 + MacroAssembler _masm(&cbuf); 1.897 + if (is_verified_oop_base) { 1.898 + __ verify_oop(reg_to_register_object(src1_enc)); 1.899 + } 1.900 + if (is_verified_oop_store) { 1.901 + __ verify_oop(reg_to_register_object(dst_enc)); 1.902 + } 1.903 + if (tmp_enc != -1) { 1.904 + __ mov(O7, reg_to_register_object(tmp_enc)); 1.905 + } 1.906 + if (is_verified_oop_load) { 1.907 + __ verify_oop(reg_to_register_object(dst_enc)); 1.908 + } 1.909 + } 1.910 +#endif 1.911 +} 1.912 + 1.913 +void emit_form3_mem_reg_asi(CodeBuffer &cbuf, const MachNode* n, int primary, int tertiary, 1.914 + int src1_enc, int disp32, int src2_enc, int dst_enc, int asi) { 1.915 + 1.916 + uint instr; 1.917 + instr = (Assembler::ldst_op << 30) 1.918 + | (dst_enc << 25) 1.919 + | (primary << 19) 1.920 + | (src1_enc << 14); 1.921 + 1.922 + int disp = disp32; 1.923 + int index = src2_enc; 1.924 + 1.925 + if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) 1.926 + disp += STACK_BIAS; 1.927 + 1.928 + // We should have a compiler bailout here rather than a guarantee. 1.929 + // Better yet would be some mechanism to handle variable-size matches correctly. 1.930 + guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" ); 1.931 + 1.932 + if( disp != 0 ) { 1.933 + // use reg-reg form 1.934 + // set src2=R_O7 contains offset 1.935 + index = R_O7_enc; 1.936 + emit3_simm13( cbuf, Assembler::arith_op, index, Assembler::or_op3, 0, disp); 1.937 + } 1.938 + instr |= (asi << 5); 1.939 + instr |= index; 1.940 + uint *code = (uint*)cbuf.code_end(); 1.941 + *code = instr; 1.942 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.943 +} 1.944 + 1.945 +void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) { 1.946 + // The method which records debug information at every safepoint 1.947 + // expects the call to be the first instruction in the snippet as 1.948 + // it creates a PcDesc structure which tracks the offset of a call 1.949 + // from the start of the codeBlob. This offset is computed as 1.950 + // code_end() - code_begin() of the code which has been emitted 1.951 + // so far. 1.952 + // In this particular case we have skirted around the problem by 1.953 + // putting the "mov" instruction in the delay slot but the problem 1.954 + // may bite us again at some other point and a cleaner/generic 1.955 + // solution using relocations would be needed. 1.956 + MacroAssembler _masm(&cbuf); 1.957 + __ set_inst_mark(); 1.958 + 1.959 + // We flush the current window just so that there is a valid stack copy 1.960 + // the fact that the current window becomes active again instantly is 1.961 + // not a problem there is nothing live in it. 1.962 + 1.963 +#ifdef ASSERT 1.964 + int startpos = __ offset(); 1.965 +#endif /* ASSERT */ 1.966 + 1.967 +#ifdef _LP64 1.968 + // Calls to the runtime or native may not be reachable from compiled code, 1.969 + // so we generate the far call sequence on 64 bit sparc. 1.970 + // This code sequence is relocatable to any address, even on LP64. 1.971 + if ( force_far_call ) { 1.972 + __ relocate(rtype); 1.973 + Address dest(O7, (address)entry_point); 1.974 + __ jumpl_to(dest, O7); 1.975 + } 1.976 + else 1.977 +#endif 1.978 + { 1.979 + __ call((address)entry_point, rtype); 1.980 + } 1.981 + 1.982 + if (preserve_g2) __ delayed()->mov(G2, L7); 1.983 + else __ delayed()->nop(); 1.984 + 1.985 + if (preserve_g2) __ mov(L7, G2); 1.986 + 1.987 +#ifdef ASSERT 1.988 + if (preserve_g2 && (VerifyCompiledCode || VerifyOops)) { 1.989 +#ifdef _LP64 1.990 + // Trash argument dump slots. 1.991 + __ set(0xb0b8ac0db0b8ac0d, G1); 1.992 + __ mov(G1, G5); 1.993 + __ stx(G1, SP, STACK_BIAS + 0x80); 1.994 + __ stx(G1, SP, STACK_BIAS + 0x88); 1.995 + __ stx(G1, SP, STACK_BIAS + 0x90); 1.996 + __ stx(G1, SP, STACK_BIAS + 0x98); 1.997 + __ stx(G1, SP, STACK_BIAS + 0xA0); 1.998 + __ stx(G1, SP, STACK_BIAS + 0xA8); 1.999 +#else // _LP64 1.1000 + // this is also a native call, so smash the first 7 stack locations, 1.1001 + // and the various registers 1.1002 + 1.1003 + // Note: [SP+0x40] is sp[callee_aggregate_return_pointer_sp_offset], 1.1004 + // while [SP+0x44..0x58] are the argument dump slots. 1.1005 + __ set((intptr_t)0xbaadf00d, G1); 1.1006 + __ mov(G1, G5); 1.1007 + __ sllx(G1, 32, G1); 1.1008 + __ or3(G1, G5, G1); 1.1009 + __ mov(G1, G5); 1.1010 + __ stx(G1, SP, 0x40); 1.1011 + __ stx(G1, SP, 0x48); 1.1012 + __ stx(G1, SP, 0x50); 1.1013 + __ stw(G1, SP, 0x58); // Do not trash [SP+0x5C] which is a usable spill slot 1.1014 +#endif // _LP64 1.1015 + } 1.1016 +#endif /*ASSERT*/ 1.1017 +} 1.1018 + 1.1019 +//============================================================================= 1.1020 +// REQUIRED FUNCTIONALITY for encoding 1.1021 +void emit_lo(CodeBuffer &cbuf, int val) { } 1.1022 +void emit_hi(CodeBuffer &cbuf, int val) { } 1.1023 + 1.1024 +void emit_ptr(CodeBuffer &cbuf, intptr_t val, Register reg, bool ForceRelocatable) { 1.1025 + MacroAssembler _masm(&cbuf); 1.1026 + if (ForceRelocatable) { 1.1027 + Address addr(reg, (address)val); 1.1028 + __ sethi(addr, ForceRelocatable); 1.1029 + __ add(addr, reg); 1.1030 + } else { 1.1031 + __ set(val, reg); 1.1032 + } 1.1033 +} 1.1034 + 1.1035 + 1.1036 +//============================================================================= 1.1037 + 1.1038 +#ifndef PRODUCT 1.1039 +void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.1040 + Compile* C = ra_->C; 1.1041 + 1.1042 + for (int i = 0; i < OptoPrologueNops; i++) { 1.1043 + st->print_cr("NOP"); st->print("\t"); 1.1044 + } 1.1045 + 1.1046 + if( VerifyThread ) { 1.1047 + st->print_cr("Verify_Thread"); st->print("\t"); 1.1048 + } 1.1049 + 1.1050 + size_t framesize = C->frame_slots() << LogBytesPerInt; 1.1051 + 1.1052 + // Calls to C2R adapters often do not accept exceptional returns. 1.1053 + // We require that their callers must bang for them. But be careful, because 1.1054 + // some VM calls (such as call site linkage) can use several kilobytes of 1.1055 + // stack. But the stack safety zone should account for that. 1.1056 + // See bugs 4446381, 4468289, 4497237. 1.1057 + if (C->need_stack_bang(framesize)) { 1.1058 + st->print_cr("! stack bang"); st->print("\t"); 1.1059 + } 1.1060 + 1.1061 + if (Assembler::is_simm13(-framesize)) { 1.1062 + st->print ("SAVE R_SP,-%d,R_SP",framesize); 1.1063 + } else { 1.1064 + st->print_cr("SETHI R_SP,hi%%(-%d),R_G3",framesize); st->print("\t"); 1.1065 + st->print_cr("ADD R_G3,lo%%(-%d),R_G3",framesize); st->print("\t"); 1.1066 + st->print ("SAVE R_SP,R_G3,R_SP"); 1.1067 + } 1.1068 + 1.1069 +} 1.1070 +#endif 1.1071 + 1.1072 +void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.1073 + Compile* C = ra_->C; 1.1074 + MacroAssembler _masm(&cbuf); 1.1075 + 1.1076 + for (int i = 0; i < OptoPrologueNops; i++) { 1.1077 + __ nop(); 1.1078 + } 1.1079 + 1.1080 + __ verify_thread(); 1.1081 + 1.1082 + size_t framesize = C->frame_slots() << LogBytesPerInt; 1.1083 + assert(framesize >= 16*wordSize, "must have room for reg. save area"); 1.1084 + assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1.1085 + 1.1086 + // Calls to C2R adapters often do not accept exceptional returns. 1.1087 + // We require that their callers must bang for them. But be careful, because 1.1088 + // some VM calls (such as call site linkage) can use several kilobytes of 1.1089 + // stack. But the stack safety zone should account for that. 1.1090 + // See bugs 4446381, 4468289, 4497237. 1.1091 + if (C->need_stack_bang(framesize)) { 1.1092 + __ generate_stack_overflow_check(framesize); 1.1093 + } 1.1094 + 1.1095 + if (Assembler::is_simm13(-framesize)) { 1.1096 + __ save(SP, -framesize, SP); 1.1097 + } else { 1.1098 + __ sethi(-framesize & ~0x3ff, G3); 1.1099 + __ add(G3, -framesize & 0x3ff, G3); 1.1100 + __ save(SP, G3, SP); 1.1101 + } 1.1102 + C->set_frame_complete( __ offset() ); 1.1103 +} 1.1104 + 1.1105 +uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1.1106 + return MachNode::size(ra_); 1.1107 +} 1.1108 + 1.1109 +int MachPrologNode::reloc() const { 1.1110 + return 10; // a large enough number 1.1111 +} 1.1112 + 1.1113 +//============================================================================= 1.1114 +#ifndef PRODUCT 1.1115 +void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.1116 + Compile* C = ra_->C; 1.1117 + 1.1118 + if( do_polling() && ra_->C->is_method_compilation() ) { 1.1119 + st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t"); 1.1120 +#ifdef _LP64 1.1121 + st->print("LDX [L0],G0\t!Poll for Safepointing\n\t"); 1.1122 +#else 1.1123 + st->print("LDUW [L0],G0\t!Poll for Safepointing\n\t"); 1.1124 +#endif 1.1125 + } 1.1126 + 1.1127 + if( do_polling() ) 1.1128 + st->print("RET\n\t"); 1.1129 + 1.1130 + st->print("RESTORE"); 1.1131 +} 1.1132 +#endif 1.1133 + 1.1134 +void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.1135 + MacroAssembler _masm(&cbuf); 1.1136 + Compile* C = ra_->C; 1.1137 + 1.1138 + __ verify_thread(); 1.1139 + 1.1140 + // If this does safepoint polling, then do it here 1.1141 + if( do_polling() && ra_->C->is_method_compilation() ) { 1.1142 + Address polling_page(L0, (address)os::get_polling_page()); 1.1143 + __ sethi(polling_page, false); 1.1144 + __ relocate(relocInfo::poll_return_type); 1.1145 + __ ld_ptr( L0, 0, G0 ); 1.1146 + } 1.1147 + 1.1148 + // If this is a return, then stuff the restore in the delay slot 1.1149 + if( do_polling() ) { 1.1150 + __ ret(); 1.1151 + __ delayed()->restore(); 1.1152 + } else { 1.1153 + __ restore(); 1.1154 + } 1.1155 +} 1.1156 + 1.1157 +uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1.1158 + return MachNode::size(ra_); 1.1159 +} 1.1160 + 1.1161 +int MachEpilogNode::reloc() const { 1.1162 + return 16; // a large enough number 1.1163 +} 1.1164 + 1.1165 +const Pipeline * MachEpilogNode::pipeline() const { 1.1166 + return MachNode::pipeline_class(); 1.1167 +} 1.1168 + 1.1169 +int MachEpilogNode::safepoint_offset() const { 1.1170 + assert( do_polling(), "no return for this epilog node"); 1.1171 + return MacroAssembler::size_of_sethi(os::get_polling_page()); 1.1172 +} 1.1173 + 1.1174 +//============================================================================= 1.1175 + 1.1176 +// Figure out which register class each belongs in: rc_int, rc_float, rc_stack 1.1177 +enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1.1178 +static enum RC rc_class( OptoReg::Name reg ) { 1.1179 + if( !OptoReg::is_valid(reg) ) return rc_bad; 1.1180 + if (OptoReg::is_stack(reg)) return rc_stack; 1.1181 + VMReg r = OptoReg::as_VMReg(reg); 1.1182 + if (r->is_Register()) return rc_int; 1.1183 + assert(r->is_FloatRegister(), "must be"); 1.1184 + return rc_float; 1.1185 +} 1.1186 + 1.1187 +static int impl_helper( const MachNode *mach, CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size, outputStream* st ) { 1.1188 + if( cbuf ) { 1.1189 + // Better yet would be some mechanism to handle variable-size matches correctly 1.1190 + if (!Assembler::is_simm13(offset + STACK_BIAS)) { 1.1191 + ra_->C->record_method_not_compilable("unable to handle large constant offsets"); 1.1192 + } else { 1.1193 + emit_form3_mem_reg(*cbuf, mach, opcode, -1, R_SP_enc, offset, 0, Matcher::_regEncode[reg]); 1.1194 + } 1.1195 + } 1.1196 +#ifndef PRODUCT 1.1197 + else if( !do_size ) { 1.1198 + if( size != 0 ) st->print("\n\t"); 1.1199 + if( is_load ) st->print("%s [R_SP + #%d],R_%s\t! spill",op_str,offset,OptoReg::regname(reg)); 1.1200 + else st->print("%s R_%s,[R_SP + #%d]\t! spill",op_str,OptoReg::regname(reg),offset); 1.1201 + } 1.1202 +#endif 1.1203 + return size+4; 1.1204 +} 1.1205 + 1.1206 +static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int op1, int op2, const char *op_str, int size, outputStream* st ) { 1.1207 + if( cbuf ) emit3( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src] ); 1.1208 +#ifndef PRODUCT 1.1209 + else if( !do_size ) { 1.1210 + if( size != 0 ) st->print("\n\t"); 1.1211 + st->print("%s R_%s,R_%s\t! spill",op_str,OptoReg::regname(src),OptoReg::regname(dst)); 1.1212 + } 1.1213 +#endif 1.1214 + return size+4; 1.1215 +} 1.1216 + 1.1217 +uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, 1.1218 + PhaseRegAlloc *ra_, 1.1219 + bool do_size, 1.1220 + outputStream* st ) const { 1.1221 + // Get registers to move 1.1222 + OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1.1223 + OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1.1224 + OptoReg::Name dst_second = ra_->get_reg_second(this ); 1.1225 + OptoReg::Name dst_first = ra_->get_reg_first(this ); 1.1226 + 1.1227 + enum RC src_second_rc = rc_class(src_second); 1.1228 + enum RC src_first_rc = rc_class(src_first); 1.1229 + enum RC dst_second_rc = rc_class(dst_second); 1.1230 + enum RC dst_first_rc = rc_class(dst_first); 1.1231 + 1.1232 + assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" ); 1.1233 + 1.1234 + // Generate spill code! 1.1235 + int size = 0; 1.1236 + 1.1237 + if( src_first == dst_first && src_second == dst_second ) 1.1238 + return size; // Self copy, no move 1.1239 + 1.1240 + // -------------------------------------- 1.1241 + // Check for mem-mem move. Load into unused float registers and fall into 1.1242 + // the float-store case. 1.1243 + if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1.1244 + int offset = ra_->reg2offset(src_first); 1.1245 + // Further check for aligned-adjacent pair, so we can use a double load 1.1246 + if( (src_first&1)==0 && src_first+1 == src_second ) { 1.1247 + src_second = OptoReg::Name(R_F31_num); 1.1248 + src_second_rc = rc_float; 1.1249 + size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::lddf_op3,"LDDF",size, st); 1.1250 + } else { 1.1251 + size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::ldf_op3 ,"LDF ",size, st); 1.1252 + } 1.1253 + src_first = OptoReg::Name(R_F30_num); 1.1254 + src_first_rc = rc_float; 1.1255 + } 1.1256 + 1.1257 + if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { 1.1258 + int offset = ra_->reg2offset(src_second); 1.1259 + size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F31_num,Assembler::ldf_op3,"LDF ",size, st); 1.1260 + src_second = OptoReg::Name(R_F31_num); 1.1261 + src_second_rc = rc_float; 1.1262 + } 1.1263 + 1.1264 + // -------------------------------------- 1.1265 + // Check for float->int copy; requires a trip through memory 1.1266 + if( src_first_rc == rc_float && dst_first_rc == rc_int ) { 1.1267 + int offset = frame::register_save_words*wordSize; 1.1268 + if( cbuf ) { 1.1269 + emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); 1.1270 + impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); 1.1271 + impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); 1.1272 + emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); 1.1273 + } 1.1274 +#ifndef PRODUCT 1.1275 + else if( !do_size ) { 1.1276 + if( size != 0 ) st->print("\n\t"); 1.1277 + st->print( "SUB R_SP,16,R_SP\n"); 1.1278 + impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); 1.1279 + impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); 1.1280 + st->print("\tADD R_SP,16,R_SP\n"); 1.1281 + } 1.1282 +#endif 1.1283 + size += 16; 1.1284 + } 1.1285 + 1.1286 + // -------------------------------------- 1.1287 + // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations. 1.1288 + // In such cases, I have to do the big-endian swap. For aligned targets, the 1.1289 + // hardware does the flop for me. Doubles are always aligned, so no problem 1.1290 + // there. Misaligned sources only come from native-long-returns (handled 1.1291 + // special below). 1.1292 +#ifndef _LP64 1.1293 + if( src_first_rc == rc_int && // source is already big-endian 1.1294 + src_second_rc != rc_bad && // 64-bit move 1.1295 + ((dst_first&1)!=0 || dst_second != dst_first+1) ) { // misaligned dst 1.1296 + assert( (src_first&1)==0 && src_second == src_first+1, "source must be aligned" ); 1.1297 + // Do the big-endian flop. 1.1298 + OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ; 1.1299 + enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc; 1.1300 + } 1.1301 +#endif 1.1302 + 1.1303 + // -------------------------------------- 1.1304 + // Check for integer reg-reg copy 1.1305 + if( src_first_rc == rc_int && dst_first_rc == rc_int ) { 1.1306 +#ifndef _LP64 1.1307 + if( src_first == R_O0_num && src_second == R_O1_num ) { // Check for the evil O0/O1 native long-return case 1.1308 + // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value 1.1309 + // as stored in memory. On a big-endian machine like SPARC, this means that the _second 1.1310 + // operand contains the least significant word of the 64-bit value and vice versa. 1.1311 + OptoReg::Name tmp = OptoReg::Name(R_O7_num); 1.1312 + assert( (dst_first&1)==0 && dst_second == dst_first+1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" ); 1.1313 + // Shift O0 left in-place, zero-extend O1, then OR them into the dst 1.1314 + if( cbuf ) { 1.1315 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020 ); 1.1316 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000 ); 1.1317 + emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second] ); 1.1318 +#ifndef PRODUCT 1.1319 + } else if( !do_size ) { 1.1320 + if( size != 0 ) st->print("\n\t"); 1.1321 + st->print("SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp)); 1.1322 + st->print("SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second)); 1.1323 + st->print("OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first)); 1.1324 +#endif 1.1325 + } 1.1326 + return size+12; 1.1327 + } 1.1328 + else if( dst_first == R_I0_num && dst_second == R_I1_num ) { 1.1329 + // returning a long value in I0/I1 1.1330 + // a SpillCopy must be able to target a return instruction's reg_class 1.1331 + // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value 1.1332 + // as stored in memory. On a big-endian machine like SPARC, this means that the _second 1.1333 + // operand contains the least significant word of the 64-bit value and vice versa. 1.1334 + OptoReg::Name tdest = dst_first; 1.1335 + 1.1336 + if (src_first == dst_first) { 1.1337 + tdest = OptoReg::Name(R_O7_num); 1.1338 + size += 4; 1.1339 + } 1.1340 + 1.1341 + if( cbuf ) { 1.1342 + assert( (src_first&1) == 0 && (src_first+1) == src_second, "return value was in an aligned-adjacent 64-bit reg"); 1.1343 + // Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1 1.1344 + // ShrL_reg_imm6 1.1345 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000 ); 1.1346 + // ShrR_reg_imm6 src, 0, dst 1.1347 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000 ); 1.1348 + if (tdest != dst_first) { 1.1349 + emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest] ); 1.1350 + } 1.1351 + } 1.1352 +#ifndef PRODUCT 1.1353 + else if( !do_size ) { 1.1354 + if( size != 0 ) st->print("\n\t"); // %%%%% !!!!! 1.1355 + st->print("SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest)); 1.1356 + st->print("SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second)); 1.1357 + if (tdest != dst_first) { 1.1358 + st->print("MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first)); 1.1359 + } 1.1360 + } 1.1361 +#endif // PRODUCT 1.1362 + return size+8; 1.1363 + } 1.1364 +#endif // !_LP64 1.1365 + // Else normal reg-reg copy 1.1366 + assert( src_second != dst_first, "smashed second before evacuating it" ); 1.1367 + size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::or_op3,0,"MOV ",size, st); 1.1368 + assert( (src_first&1) == 0 && (dst_first&1) == 0, "never move second-halves of int registers" ); 1.1369 + // This moves an aligned adjacent pair. 1.1370 + // See if we are done. 1.1371 + if( src_first+1 == src_second && dst_first+1 == dst_second ) 1.1372 + return size; 1.1373 + } 1.1374 + 1.1375 + // Check for integer store 1.1376 + if( src_first_rc == rc_int && dst_first_rc == rc_stack ) { 1.1377 + int offset = ra_->reg2offset(dst_first); 1.1378 + // Further check for aligned-adjacent pair, so we can use a double store 1.1379 + if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) 1.1380 + return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stx_op3,"STX ",size, st); 1.1381 + size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stw_op3,"STW ",size, st); 1.1382 + } 1.1383 + 1.1384 + // Check for integer load 1.1385 + if( dst_first_rc == rc_int && src_first_rc == rc_stack ) { 1.1386 + int offset = ra_->reg2offset(src_first); 1.1387 + // Further check for aligned-adjacent pair, so we can use a double load 1.1388 + if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) 1.1389 + return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldx_op3 ,"LDX ",size, st); 1.1390 + size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); 1.1391 + } 1.1392 + 1.1393 + // Check for float reg-reg copy 1.1394 + if( src_first_rc == rc_float && dst_first_rc == rc_float ) { 1.1395 + // Further check for aligned-adjacent pair, so we can use a double move 1.1396 + if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) 1.1397 + return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovd_opf,"FMOVD",size, st); 1.1398 + size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovs_opf,"FMOVS",size, st); 1.1399 + } 1.1400 + 1.1401 + // Check for float store 1.1402 + if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1.1403 + int offset = ra_->reg2offset(dst_first); 1.1404 + // Further check for aligned-adjacent pair, so we can use a double store 1.1405 + if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) 1.1406 + return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stdf_op3,"STDF",size, st); 1.1407 + size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); 1.1408 + } 1.1409 + 1.1410 + // Check for float load 1.1411 + if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { 1.1412 + int offset = ra_->reg2offset(src_first); 1.1413 + // Further check for aligned-adjacent pair, so we can use a double load 1.1414 + if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) 1.1415 + return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lddf_op3,"LDDF",size, st); 1.1416 + size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldf_op3 ,"LDF ",size, st); 1.1417 + } 1.1418 + 1.1419 + // -------------------------------------------------------------------- 1.1420 + // Check for hi bits still needing moving. Only happens for misaligned 1.1421 + // arguments to native calls. 1.1422 + if( src_second == dst_second ) 1.1423 + return size; // Self copy; no move 1.1424 + assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); 1.1425 + 1.1426 +#ifndef _LP64 1.1427 + // In the LP64 build, all registers can be moved as aligned/adjacent 1.1428 + // pairs, so there's never any need to move the high bits seperately. 1.1429 + // The 32-bit builds have to deal with the 32-bit ABI which can force 1.1430 + // all sorts of silly alignment problems. 1.1431 + 1.1432 + // Check for integer reg-reg copy. Hi bits are stuck up in the top 1.1433 + // 32-bits of a 64-bit register, but are needed in low bits of another 1.1434 + // register (else it's a hi-bits-to-hi-bits copy which should have 1.1435 + // happened already as part of a 64-bit move) 1.1436 + if( src_second_rc == rc_int && dst_second_rc == rc_int ) { 1.1437 + assert( (src_second&1)==1, "its the evil O0/O1 native return case" ); 1.1438 + assert( (dst_second&1)==0, "should have moved with 1 64-bit move" ); 1.1439 + // Shift src_second down to dst_second's low bits. 1.1440 + if( cbuf ) { 1.1441 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); 1.1442 +#ifndef PRODUCT 1.1443 + } else if( !do_size ) { 1.1444 + if( size != 0 ) st->print("\n\t"); 1.1445 + st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(dst_second)); 1.1446 +#endif 1.1447 + } 1.1448 + return size+4; 1.1449 + } 1.1450 + 1.1451 + // Check for high word integer store. Must down-shift the hi bits 1.1452 + // into a temp register, then fall into the case of storing int bits. 1.1453 + if( src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second&1)==1 ) { 1.1454 + // Shift src_second down to dst_second's low bits. 1.1455 + if( cbuf ) { 1.1456 + emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); 1.1457 +#ifndef PRODUCT 1.1458 + } else if( !do_size ) { 1.1459 + if( size != 0 ) st->print("\n\t"); 1.1460 + st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(R_O7_num)); 1.1461 +#endif 1.1462 + } 1.1463 + size+=4; 1.1464 + src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num! 1.1465 + } 1.1466 + 1.1467 + // Check for high word integer load 1.1468 + if( dst_second_rc == rc_int && src_second_rc == rc_stack ) 1.1469 + return impl_helper(this,cbuf,ra_,do_size,true ,ra_->reg2offset(src_second),dst_second,Assembler::lduw_op3,"LDUW",size, st); 1.1470 + 1.1471 + // Check for high word integer store 1.1472 + if( src_second_rc == rc_int && dst_second_rc == rc_stack ) 1.1473 + return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stw_op3 ,"STW ",size, st); 1.1474 + 1.1475 + // Check for high word float store 1.1476 + if( src_second_rc == rc_float && dst_second_rc == rc_stack ) 1.1477 + return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stf_op3 ,"STF ",size, st); 1.1478 + 1.1479 +#endif // !_LP64 1.1480 + 1.1481 + Unimplemented(); 1.1482 +} 1.1483 + 1.1484 +#ifndef PRODUCT 1.1485 +void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.1486 + implementation( NULL, ra_, false, st ); 1.1487 +} 1.1488 +#endif 1.1489 + 1.1490 +void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.1491 + implementation( &cbuf, ra_, false, NULL ); 1.1492 +} 1.1493 + 1.1494 +uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1.1495 + return implementation( NULL, ra_, true, NULL ); 1.1496 +} 1.1497 + 1.1498 +//============================================================================= 1.1499 +#ifndef PRODUCT 1.1500 +void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const { 1.1501 + st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count); 1.1502 +} 1.1503 +#endif 1.1504 + 1.1505 +void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const { 1.1506 + MacroAssembler _masm(&cbuf); 1.1507 + for(int i = 0; i < _count; i += 1) { 1.1508 + __ nop(); 1.1509 + } 1.1510 +} 1.1511 + 1.1512 +uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1.1513 + return 4 * _count; 1.1514 +} 1.1515 + 1.1516 + 1.1517 +//============================================================================= 1.1518 +#ifndef PRODUCT 1.1519 +void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.1520 + int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1.1521 + int reg = ra_->get_reg_first(this); 1.1522 + st->print("LEA [R_SP+#%d+BIAS],%s",offset,Matcher::regName[reg]); 1.1523 +} 1.1524 +#endif 1.1525 + 1.1526 +void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.1527 + MacroAssembler _masm(&cbuf); 1.1528 + int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()) + STACK_BIAS; 1.1529 + int reg = ra_->get_encode(this); 1.1530 + 1.1531 + if (Assembler::is_simm13(offset)) { 1.1532 + __ add(SP, offset, reg_to_register_object(reg)); 1.1533 + } else { 1.1534 + __ set(offset, O7); 1.1535 + __ add(SP, O7, reg_to_register_object(reg)); 1.1536 + } 1.1537 +} 1.1538 + 1.1539 +uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1.1540 + // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_) 1.1541 + assert(ra_ == ra_->C->regalloc(), "sanity"); 1.1542 + return ra_->C->scratch_emit_size(this); 1.1543 +} 1.1544 + 1.1545 +//============================================================================= 1.1546 + 1.1547 +// emit call stub, compiled java to interpretor 1.1548 +void emit_java_to_interp(CodeBuffer &cbuf ) { 1.1549 + 1.1550 + // Stub is fixed up when the corresponding call is converted from calling 1.1551 + // compiled code to calling interpreted code. 1.1552 + // set (empty), G5 1.1553 + // jmp -1 1.1554 + 1.1555 + address mark = cbuf.inst_mark(); // get mark within main instrs section 1.1556 + 1.1557 + MacroAssembler _masm(&cbuf); 1.1558 + 1.1559 + address base = 1.1560 + __ start_a_stub(Compile::MAX_stubs_size); 1.1561 + if (base == NULL) return; // CodeBuffer::expand failed 1.1562 + 1.1563 + // static stub relocation stores the instruction address of the call 1.1564 + __ relocate(static_stub_Relocation::spec(mark)); 1.1565 + 1.1566 + __ set_oop(NULL, reg_to_register_object(Matcher::inline_cache_reg_encode())); 1.1567 + 1.1568 + __ set_inst_mark(); 1.1569 + Address a(G3, (address)-1); 1.1570 + __ JUMP(a, 0); 1.1571 + 1.1572 + __ delayed()->nop(); 1.1573 + 1.1574 + // Update current stubs pointer and restore code_end. 1.1575 + __ end_a_stub(); 1.1576 +} 1.1577 + 1.1578 +// size of call stub, compiled java to interpretor 1.1579 +uint size_java_to_interp() { 1.1580 + // This doesn't need to be accurate but it must be larger or equal to 1.1581 + // the real size of the stub. 1.1582 + return (NativeMovConstReg::instruction_size + // sethi/setlo; 1.1583 + NativeJump::instruction_size + // sethi; jmp; nop 1.1584 + (TraceJumps ? 20 * BytesPerInstWord : 0) ); 1.1585 +} 1.1586 +// relocation entries for call stub, compiled java to interpretor 1.1587 +uint reloc_java_to_interp() { 1.1588 + return 10; // 4 in emit_java_to_interp + 1 in Java_Static_Call 1.1589 +} 1.1590 + 1.1591 + 1.1592 +//============================================================================= 1.1593 +#ifndef PRODUCT 1.1594 +void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.1595 + st->print_cr("\nUEP:"); 1.1596 +#ifdef _LP64 1.1597 + st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); 1.1598 + st->print_cr("\tCMP R_G5,R_G3" ); 1.1599 + st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2"); 1.1600 +#else // _LP64 1.1601 + st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); 1.1602 + st->print_cr("\tCMP R_G5,R_G3" ); 1.1603 + st->print ("\tTne icc,R_G0+ST_RESERVED_FOR_USER_0+2"); 1.1604 +#endif // _LP64 1.1605 +} 1.1606 +#endif 1.1607 + 1.1608 +void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1.1609 + MacroAssembler _masm(&cbuf); 1.1610 + Label L; 1.1611 + Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); 1.1612 + Register temp_reg = G3; 1.1613 + assert( G5_ic_reg != temp_reg, "conflicting registers" ); 1.1614 + 1.1615 + // Load klass from reciever 1.1616 + __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg); 1.1617 + // Compare against expected klass 1.1618 + __ cmp(temp_reg, G5_ic_reg); 1.1619 + // Branch to miss code, checks xcc or icc depending 1.1620 + __ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2); 1.1621 +} 1.1622 + 1.1623 +uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1.1624 + return MachNode::size(ra_); 1.1625 +} 1.1626 + 1.1627 + 1.1628 +//============================================================================= 1.1629 + 1.1630 +uint size_exception_handler() { 1.1631 + if (TraceJumps) { 1.1632 + return (400); // just a guess 1.1633 + } 1.1634 + return ( NativeJump::instruction_size ); // sethi;jmp;nop 1.1635 +} 1.1636 + 1.1637 +uint size_deopt_handler() { 1.1638 + if (TraceJumps) { 1.1639 + return (400); // just a guess 1.1640 + } 1.1641 + return ( 4+ NativeJump::instruction_size ); // save;sethi;jmp;restore 1.1642 +} 1.1643 + 1.1644 +// Emit exception handler code. 1.1645 +int emit_exception_handler(CodeBuffer& cbuf) { 1.1646 + Register temp_reg = G3; 1.1647 + Address exception_blob(temp_reg, OptoRuntime::exception_blob()->instructions_begin()); 1.1648 + MacroAssembler _masm(&cbuf); 1.1649 + 1.1650 + address base = 1.1651 + __ start_a_stub(size_exception_handler()); 1.1652 + if (base == NULL) return 0; // CodeBuffer::expand failed 1.1653 + 1.1654 + int offset = __ offset(); 1.1655 + 1.1656 + __ JUMP(exception_blob, 0); // sethi;jmp 1.1657 + __ delayed()->nop(); 1.1658 + 1.1659 + assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1.1660 + 1.1661 + __ end_a_stub(); 1.1662 + 1.1663 + return offset; 1.1664 +} 1.1665 + 1.1666 +int emit_deopt_handler(CodeBuffer& cbuf) { 1.1667 + // Can't use any of the current frame's registers as we may have deopted 1.1668 + // at a poll and everything (including G3) can be live. 1.1669 + Register temp_reg = L0; 1.1670 + Address deopt_blob(temp_reg, SharedRuntime::deopt_blob()->unpack()); 1.1671 + MacroAssembler _masm(&cbuf); 1.1672 + 1.1673 + address base = 1.1674 + __ start_a_stub(size_deopt_handler()); 1.1675 + if (base == NULL) return 0; // CodeBuffer::expand failed 1.1676 + 1.1677 + int offset = __ offset(); 1.1678 + __ save_frame(0); 1.1679 + __ JUMP(deopt_blob, 0); // sethi;jmp 1.1680 + __ delayed()->restore(); 1.1681 + 1.1682 + assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1.1683 + 1.1684 + __ end_a_stub(); 1.1685 + return offset; 1.1686 + 1.1687 +} 1.1688 + 1.1689 +// Given a register encoding, produce a Integer Register object 1.1690 +static Register reg_to_register_object(int register_encoding) { 1.1691 + assert(L5->encoding() == R_L5_enc && G1->encoding() == R_G1_enc, "right coding"); 1.1692 + return as_Register(register_encoding); 1.1693 +} 1.1694 + 1.1695 +// Given a register encoding, produce a single-precision Float Register object 1.1696 +static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding) { 1.1697 + assert(F5->encoding(FloatRegisterImpl::S) == R_F5_enc && F12->encoding(FloatRegisterImpl::S) == R_F12_enc, "right coding"); 1.1698 + return as_SingleFloatRegister(register_encoding); 1.1699 +} 1.1700 + 1.1701 +// Given a register encoding, produce a double-precision Float Register object 1.1702 +static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) { 1.1703 + assert(F4->encoding(FloatRegisterImpl::D) == R_F4_enc, "right coding"); 1.1704 + assert(F32->encoding(FloatRegisterImpl::D) == R_D32_enc, "right coding"); 1.1705 + return as_DoubleFloatRegister(register_encoding); 1.1706 +} 1.1707 + 1.1708 +int Matcher::regnum_to_fpu_offset(int regnum) { 1.1709 + return regnum - 32; // The FP registers are in the second chunk 1.1710 +} 1.1711 + 1.1712 +#ifdef ASSERT 1.1713 +address last_rethrow = NULL; // debugging aid for Rethrow encoding 1.1714 +#endif 1.1715 + 1.1716 +// Vector width in bytes 1.1717 +const uint Matcher::vector_width_in_bytes(void) { 1.1718 + return 8; 1.1719 +} 1.1720 + 1.1721 +// Vector ideal reg 1.1722 +const uint Matcher::vector_ideal_reg(void) { 1.1723 + return Op_RegD; 1.1724 +} 1.1725 + 1.1726 +// USII supports fxtof through the whole range of number, USIII doesn't 1.1727 +const bool Matcher::convL2FSupported(void) { 1.1728 + return VM_Version::has_fast_fxtof(); 1.1729 +} 1.1730 + 1.1731 +// Is this branch offset short enough that a short branch can be used? 1.1732 +// 1.1733 +// NOTE: If the platform does not provide any short branch variants, then 1.1734 +// this method should return false for offset 0. 1.1735 +bool Matcher::is_short_branch_offset(int offset) { 1.1736 + return false; 1.1737 +} 1.1738 + 1.1739 +const bool Matcher::isSimpleConstant64(jlong value) { 1.1740 + // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1.1741 + // Depends on optimizations in MacroAssembler::setx. 1.1742 + int hi = (int)(value >> 32); 1.1743 + int lo = (int)(value & ~0); 1.1744 + return (hi == 0) || (hi == -1) || (lo == 0); 1.1745 +} 1.1746 + 1.1747 +// No scaling for the parameter the ClearArray node. 1.1748 +const bool Matcher::init_array_count_is_in_bytes = true; 1.1749 + 1.1750 +// Threshold size for cleararray. 1.1751 +const int Matcher::init_array_short_size = 8 * BytesPerLong; 1.1752 + 1.1753 +// Should the Matcher clone shifts on addressing modes, expecting them to 1.1754 +// be subsumed into complex addressing expressions or compute them into 1.1755 +// registers? True for Intel but false for most RISCs 1.1756 +const bool Matcher::clone_shift_expressions = false; 1.1757 + 1.1758 +// Is it better to copy float constants, or load them directly from memory? 1.1759 +// Intel can load a float constant from a direct address, requiring no 1.1760 +// extra registers. Most RISCs will have to materialize an address into a 1.1761 +// register first, so they would do better to copy the constant from stack. 1.1762 +const bool Matcher::rematerialize_float_constants = false; 1.1763 + 1.1764 +// If CPU can load and store mis-aligned doubles directly then no fixup is 1.1765 +// needed. Else we split the double into 2 integer pieces and move it 1.1766 +// piece-by-piece. Only happens when passing doubles into C code as the 1.1767 +// Java calling convention forces doubles to be aligned. 1.1768 +#ifdef _LP64 1.1769 +const bool Matcher::misaligned_doubles_ok = true; 1.1770 +#else 1.1771 +const bool Matcher::misaligned_doubles_ok = false; 1.1772 +#endif 1.1773 + 1.1774 +// No-op on SPARC. 1.1775 +void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 1.1776 +} 1.1777 + 1.1778 +// Advertise here if the CPU requires explicit rounding operations 1.1779 +// to implement the UseStrictFP mode. 1.1780 +const bool Matcher::strict_fp_requires_explicit_rounding = false; 1.1781 + 1.1782 +// Do floats take an entire double register or just half? 1.1783 +const bool Matcher::float_in_double = false; 1.1784 + 1.1785 +// Do ints take an entire long register or just half? 1.1786 +// Note that we if-def off of _LP64. 1.1787 +// The relevant question is how the int is callee-saved. In _LP64 1.1788 +// the whole long is written but de-opt'ing will have to extract 1.1789 +// the relevant 32 bits, in not-_LP64 only the low 32 bits is written. 1.1790 +#ifdef _LP64 1.1791 +const bool Matcher::int_in_long = true; 1.1792 +#else 1.1793 +const bool Matcher::int_in_long = false; 1.1794 +#endif 1.1795 + 1.1796 +// Return whether or not this register is ever used as an argument. This 1.1797 +// function is used on startup to build the trampoline stubs in generateOptoStub. 1.1798 +// Registers not mentioned will be killed by the VM call in the trampoline, and 1.1799 +// arguments in those registers not be available to the callee. 1.1800 +bool Matcher::can_be_java_arg( int reg ) { 1.1801 + // Standard sparc 6 args in registers 1.1802 + if( reg == R_I0_num || 1.1803 + reg == R_I1_num || 1.1804 + reg == R_I2_num || 1.1805 + reg == R_I3_num || 1.1806 + reg == R_I4_num || 1.1807 + reg == R_I5_num ) return true; 1.1808 +#ifdef _LP64 1.1809 + // 64-bit builds can pass 64-bit pointers and longs in 1.1810 + // the high I registers 1.1811 + if( reg == R_I0H_num || 1.1812 + reg == R_I1H_num || 1.1813 + reg == R_I2H_num || 1.1814 + reg == R_I3H_num || 1.1815 + reg == R_I4H_num || 1.1816 + reg == R_I5H_num ) return true; 1.1817 +#else 1.1818 + // 32-bit builds with longs-in-one-entry pass longs in G1 & G4. 1.1819 + // Longs cannot be passed in O regs, because O regs become I regs 1.1820 + // after a 'save' and I regs get their high bits chopped off on 1.1821 + // interrupt. 1.1822 + if( reg == R_G1H_num || reg == R_G1_num ) return true; 1.1823 + if( reg == R_G4H_num || reg == R_G4_num ) return true; 1.1824 +#endif 1.1825 + // A few float args in registers 1.1826 + if( reg >= R_F0_num && reg <= R_F7_num ) return true; 1.1827 + 1.1828 + return false; 1.1829 +} 1.1830 + 1.1831 +bool Matcher::is_spillable_arg( int reg ) { 1.1832 + return can_be_java_arg(reg); 1.1833 +} 1.1834 + 1.1835 +// Register for DIVI projection of divmodI 1.1836 +RegMask Matcher::divI_proj_mask() { 1.1837 + ShouldNotReachHere(); 1.1838 + return RegMask(); 1.1839 +} 1.1840 + 1.1841 +// Register for MODI projection of divmodI 1.1842 +RegMask Matcher::modI_proj_mask() { 1.1843 + ShouldNotReachHere(); 1.1844 + return RegMask(); 1.1845 +} 1.1846 + 1.1847 +// Register for DIVL projection of divmodL 1.1848 +RegMask Matcher::divL_proj_mask() { 1.1849 + ShouldNotReachHere(); 1.1850 + return RegMask(); 1.1851 +} 1.1852 + 1.1853 +// Register for MODL projection of divmodL 1.1854 +RegMask Matcher::modL_proj_mask() { 1.1855 + ShouldNotReachHere(); 1.1856 + return RegMask(); 1.1857 +} 1.1858 + 1.1859 +%} 1.1860 + 1.1861 + 1.1862 +// The intptr_t operand types, defined by textual substitution. 1.1863 +// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.) 1.1864 +#ifdef _LP64 1.1865 +#define immX immL 1.1866 +#define immX13 immL13 1.1867 +#define iRegX iRegL 1.1868 +#define g1RegX g1RegL 1.1869 +#else 1.1870 +#define immX immI 1.1871 +#define immX13 immI13 1.1872 +#define iRegX iRegI 1.1873 +#define g1RegX g1RegI 1.1874 +#endif 1.1875 + 1.1876 +//----------ENCODING BLOCK----------------------------------------------------- 1.1877 +// This block specifies the encoding classes used by the compiler to output 1.1878 +// byte streams. Encoding classes are parameterized macros used by 1.1879 +// Machine Instruction Nodes in order to generate the bit encoding of the 1.1880 +// instruction. Operands specify their base encoding interface with the 1.1881 +// interface keyword. There are currently supported four interfaces, 1.1882 +// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 1.1883 +// operand to generate a function which returns its register number when 1.1884 +// queried. CONST_INTER causes an operand to generate a function which 1.1885 +// returns the value of the constant when queried. MEMORY_INTER causes an 1.1886 +// operand to generate four functions which return the Base Register, the 1.1887 +// Index Register, the Scale Value, and the Offset Value of the operand when 1.1888 +// queried. COND_INTER causes an operand to generate six functions which 1.1889 +// return the encoding code (ie - encoding bits for the instruction) 1.1890 +// associated with each basic boolean condition for a conditional instruction. 1.1891 +// 1.1892 +// Instructions specify two basic values for encoding. Again, a function 1.1893 +// is available to check if the constant displacement is an oop. They use the 1.1894 +// ins_encode keyword to specify their encoding classes (which must be 1.1895 +// a sequence of enc_class names, and their parameters, specified in 1.1896 +// the encoding block), and they use the 1.1897 +// opcode keyword to specify, in order, their primary, secondary, and 1.1898 +// tertiary opcode. Only the opcode sections which a particular instruction 1.1899 +// needs for encoding need to be specified. 1.1900 +encode %{ 1.1901 + enc_class enc_untested %{ 1.1902 +#ifdef ASSERT 1.1903 + MacroAssembler _masm(&cbuf); 1.1904 + __ untested("encoding"); 1.1905 +#endif 1.1906 + %} 1.1907 + 1.1908 + enc_class form3_mem_reg( memory mem, iRegI dst ) %{ 1.1909 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, 1.1910 + $mem$$base, $mem$$disp, $mem$$index, $dst$$reg); 1.1911 + %} 1.1912 + 1.1913 + enc_class form3_mem_reg_little( memory mem, iRegI dst) %{ 1.1914 + emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary, 1.1915 + $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE); 1.1916 + %} 1.1917 + 1.1918 + enc_class form3_mem_prefetch_read( memory mem ) %{ 1.1919 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, 1.1920 + $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/); 1.1921 + %} 1.1922 + 1.1923 + enc_class form3_mem_prefetch_write( memory mem ) %{ 1.1924 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, 1.1925 + $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/); 1.1926 + %} 1.1927 + 1.1928 + enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{ 1.1929 + assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); 1.1930 + assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); 1.1931 + guarantee($mem$$index == R_G0_enc, "double index?"); 1.1932 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc ); 1.1933 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg ); 1.1934 + emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 ); 1.1935 + emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc ); 1.1936 + %} 1.1937 + 1.1938 + enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{ 1.1939 + assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); 1.1940 + assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); 1.1941 + guarantee($mem$$index == R_G0_enc, "double index?"); 1.1942 + // Load long with 2 instructions 1.1943 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 ); 1.1944 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 ); 1.1945 + %} 1.1946 + 1.1947 + //%%% form3_mem_plus_4_reg is a hack--get rid of it 1.1948 + enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{ 1.1949 + guarantee($mem$$disp, "cannot offset a reg-reg operand by 4"); 1.1950 + emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg); 1.1951 + %} 1.1952 + 1.1953 + enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{ 1.1954 + // Encode a reg-reg copy. If it is useless, then empty encoding. 1.1955 + if( $rs2$$reg != $rd$$reg ) 1.1956 + emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, $rs2$$reg ); 1.1957 + %} 1.1958 + 1.1959 + // Target lo half of long 1.1960 + enc_class form3_g0_rs2_rd_move_lo( iRegI rs2, iRegL rd ) %{ 1.1961 + // Encode a reg-reg copy. If it is useless, then empty encoding. 1.1962 + if( $rs2$$reg != LONG_LO_REG($rd$$reg) ) 1.1963 + emit3( cbuf, Assembler::arith_op, LONG_LO_REG($rd$$reg), Assembler::or_op3, 0, 0, $rs2$$reg ); 1.1964 + %} 1.1965 + 1.1966 + // Source lo half of long 1.1967 + enc_class form3_g0_rs2_rd_move_lo2( iRegL rs2, iRegI rd ) %{ 1.1968 + // Encode a reg-reg copy. If it is useless, then empty encoding. 1.1969 + if( LONG_LO_REG($rs2$$reg) != $rd$$reg ) 1.1970 + emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, LONG_LO_REG($rs2$$reg) ); 1.1971 + %} 1.1972 + 1.1973 + // Target hi half of long 1.1974 + enc_class form3_rs1_rd_copysign_hi( iRegI rs1, iRegL rd ) %{ 1.1975 + emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::sra_op3, $rs1$$reg, 31 ); 1.1976 + %} 1.1977 + 1.1978 + // Source lo half of long, and leave it sign extended. 1.1979 + enc_class form3_rs1_rd_signextend_lo1( iRegL rs1, iRegI rd ) %{ 1.1980 + // Sign extend low half 1.1981 + emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::sra_op3, $rs1$$reg, 0, 0 ); 1.1982 + %} 1.1983 + 1.1984 + // Source hi half of long, and leave it sign extended. 1.1985 + enc_class form3_rs1_rd_copy_hi1( iRegL rs1, iRegI rd ) %{ 1.1986 + // Shift high half to low half 1.1987 + emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::srlx_op3, $rs1$$reg, 32 ); 1.1988 + %} 1.1989 + 1.1990 + // Source hi half of long 1.1991 + enc_class form3_g0_rs2_rd_move_hi2( iRegL rs2, iRegI rd ) %{ 1.1992 + // Encode a reg-reg copy. If it is useless, then empty encoding. 1.1993 + if( LONG_HI_REG($rs2$$reg) != $rd$$reg ) 1.1994 + emit3( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0, LONG_HI_REG($rs2$$reg) ); 1.1995 + %} 1.1996 + 1.1997 + enc_class form3_rs1_rs2_rd( iRegI rs1, iRegI rs2, iRegI rd ) %{ 1.1998 + emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, 0, $rs2$$reg ); 1.1999 + %} 1.2000 + 1.2001 + enc_class enc_to_bool( iRegI src, iRegI dst ) %{ 1.2002 + emit3 ( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, 0, 0, $src$$reg ); 1.2003 + emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::addc_op3 , 0, 0 ); 1.2004 + %} 1.2005 + 1.2006 + enc_class enc_ltmask( iRegI p, iRegI q, iRegI dst ) %{ 1.2007 + emit3 ( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, $p$$reg, 0, $q$$reg ); 1.2008 + // clear if nothing else is happening 1.2009 + emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, 0 ); 1.2010 + // blt,a,pn done 1.2011 + emit2_19 ( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::less, Assembler::bp_op2, Assembler::icc, 0/*predict not taken*/, 2 ); 1.2012 + // mov dst,-1 in delay slot 1.2013 + emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, -1 ); 1.2014 + %} 1.2015 + 1.2016 + enc_class form3_rs1_imm5_rd( iRegI rs1, immU5 imm5, iRegI rd ) %{ 1.2017 + emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $imm5$$constant & 0x1F ); 1.2018 + %} 1.2019 + 1.2020 + enc_class form3_sd_rs1_imm6_rd( iRegL rs1, immU6 imm6, iRegL rd ) %{ 1.2021 + emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, ($imm6$$constant & 0x3F) | 0x1000 ); 1.2022 + %} 1.2023 + 1.2024 + enc_class form3_sd_rs1_rs2_rd( iRegL rs1, iRegI rs2, iRegL rd ) %{ 1.2025 + emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, 0x80, $rs2$$reg ); 1.2026 + %} 1.2027 + 1.2028 + enc_class form3_rs1_simm13_rd( iRegI rs1, immI13 simm13, iRegI rd ) %{ 1.2029 + emit3_simm13( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $simm13$$constant ); 1.2030 + %} 1.2031 + 1.2032 + enc_class move_return_pc_to_o1() %{ 1.2033 + emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::add_op3, R_O7_enc, frame::pc_return_offset ); 1.2034 + %} 1.2035 + 1.2036 +#ifdef _LP64 1.2037 + /* %%% merge with enc_to_bool */ 1.2038 + enc_class enc_convP2B( iRegI dst, iRegP src ) %{ 1.2039 + MacroAssembler _masm(&cbuf); 1.2040 + 1.2041 + Register src_reg = reg_to_register_object($src$$reg); 1.2042 + Register dst_reg = reg_to_register_object($dst$$reg); 1.2043 + __ movr(Assembler::rc_nz, src_reg, 1, dst_reg); 1.2044 + %} 1.2045 +#endif 1.2046 + 1.2047 + enc_class enc_cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp ) %{ 1.2048 + // (Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))) 1.2049 + MacroAssembler _masm(&cbuf); 1.2050 + 1.2051 + Register p_reg = reg_to_register_object($p$$reg); 1.2052 + Register q_reg = reg_to_register_object($q$$reg); 1.2053 + Register y_reg = reg_to_register_object($y$$reg); 1.2054 + Register tmp_reg = reg_to_register_object($tmp$$reg); 1.2055 + 1.2056 + __ subcc( p_reg, q_reg, p_reg ); 1.2057 + __ add ( p_reg, y_reg, tmp_reg ); 1.2058 + __ movcc( Assembler::less, false, Assembler::icc, tmp_reg, p_reg ); 1.2059 + %} 1.2060 + 1.2061 + enc_class form_d2i_helper(regD src, regF dst) %{ 1.2062 + // fcmp %fcc0,$src,$src 1.2063 + emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmpd_opf, $src$$reg ); 1.2064 + // branch %fcc0 not-nan, predict taken 1.2065 + emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); 1.2066 + // fdtoi $src,$dst 1.2067 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fdtoi_opf, $src$$reg ); 1.2068 + // fitos $dst,$dst (if nan) 1.2069 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fitos_opf, $dst$$reg ); 1.2070 + // clear $dst (if nan) 1.2071 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubs_opf, $dst$$reg ); 1.2072 + // carry on here... 1.2073 + %} 1.2074 + 1.2075 + enc_class form_d2l_helper(regD src, regD dst) %{ 1.2076 + // fcmp %fcc0,$src,$src check for NAN 1.2077 + emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmpd_opf, $src$$reg ); 1.2078 + // branch %fcc0 not-nan, predict taken 1.2079 + emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); 1.2080 + // fdtox $src,$dst convert in delay slot 1.2081 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fdtox_opf, $src$$reg ); 1.2082 + // fxtod $dst,$dst (if nan) 1.2083 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fxtod_opf, $dst$$reg ); 1.2084 + // clear $dst (if nan) 1.2085 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubd_opf, $dst$$reg ); 1.2086 + // carry on here... 1.2087 + %} 1.2088 + 1.2089 + enc_class form_f2i_helper(regF src, regF dst) %{ 1.2090 + // fcmps %fcc0,$src,$src 1.2091 + emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmps_opf, $src$$reg ); 1.2092 + // branch %fcc0 not-nan, predict taken 1.2093 + emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); 1.2094 + // fstoi $src,$dst 1.2095 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fstoi_opf, $src$$reg ); 1.2096 + // fitos $dst,$dst (if nan) 1.2097 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fitos_opf, $dst$$reg ); 1.2098 + // clear $dst (if nan) 1.2099 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubs_opf, $dst$$reg ); 1.2100 + // carry on here... 1.2101 + %} 1.2102 + 1.2103 + enc_class form_f2l_helper(regF src, regD dst) %{ 1.2104 + // fcmps %fcc0,$src,$src 1.2105 + emit3( cbuf, Assembler::arith_op , Assembler::fcc0, Assembler::fpop2_op3, $src$$reg, Assembler::fcmps_opf, $src$$reg ); 1.2106 + // branch %fcc0 not-nan, predict taken 1.2107 + emit2_19( cbuf, Assembler::branch_op, 0/*annul*/, Assembler::f_ordered, Assembler::fbp_op2, Assembler::fcc0, 1/*predict taken*/, 4 ); 1.2108 + // fstox $src,$dst 1.2109 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fstox_opf, $src$$reg ); 1.2110 + // fxtod $dst,$dst (if nan) 1.2111 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, 0, Assembler::fxtod_opf, $dst$$reg ); 1.2112 + // clear $dst (if nan) 1.2113 + emit3( cbuf, Assembler::arith_op , $dst$$reg, Assembler::fpop1_op3, $dst$$reg, Assembler::fsubd_opf, $dst$$reg ); 1.2114 + // carry on here... 1.2115 + %} 1.2116 + 1.2117 + enc_class form3_opf_rs2F_rdF(regF rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} 1.2118 + enc_class form3_opf_rs2F_rdD(regF rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} 1.2119 + enc_class form3_opf_rs2D_rdF(regD rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} 1.2120 + enc_class form3_opf_rs2D_rdD(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} 1.2121 + 1.2122 + enc_class form3_opf_rs2D_lo_rdF(regD rs2, regF rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg+1); %} 1.2123 + 1.2124 + enc_class form3_opf_rs2D_hi_rdD_hi(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg,$primary,0,$tertiary,$rs2$$reg); %} 1.2125 + enc_class form3_opf_rs2D_lo_rdD_lo(regD rs2, regD rd) %{ emit3(cbuf,$secondary,$rd$$reg+1,$primary,0,$tertiary,$rs2$$reg+1); %} 1.2126 + 1.2127 + enc_class form3_opf_rs1F_rs2F_rdF( regF rs1, regF rs2, regF rd ) %{ 1.2128 + emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); 1.2129 + %} 1.2130 + 1.2131 + enc_class form3_opf_rs1D_rs2D_rdD( regD rs1, regD rs2, regD rd ) %{ 1.2132 + emit3( cbuf, $secondary, $rd$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); 1.2133 + %} 1.2134 + 1.2135 + enc_class form3_opf_rs1F_rs2F_fcc( regF rs1, regF rs2, flagsRegF fcc ) %{ 1.2136 + emit3( cbuf, $secondary, $fcc$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); 1.2137 + %} 1.2138 + 1.2139 + enc_class form3_opf_rs1D_rs2D_fcc( regD rs1, regD rs2, flagsRegF fcc ) %{ 1.2140 + emit3( cbuf, $secondary, $fcc$$reg, $primary, $rs1$$reg, $tertiary, $rs2$$reg ); 1.2141 + %} 1.2142 + 1.2143 + enc_class form3_convI2F(regF rs2, regF rd) %{ 1.2144 + emit3(cbuf,Assembler::arith_op,$rd$$reg,Assembler::fpop1_op3,0,$secondary,$rs2$$reg); 1.2145 + %} 1.2146 + 1.2147 + // Encloding class for traceable jumps 1.2148 + enc_class form_jmpl(g3RegP dest) %{ 1.2149 + emit_jmpl(cbuf, $dest$$reg); 1.2150 + %} 1.2151 + 1.2152 + enc_class form_jmpl_set_exception_pc(g1RegP dest) %{ 1.2153 + emit_jmpl_set_exception_pc(cbuf, $dest$$reg); 1.2154 + %} 1.2155 + 1.2156 + enc_class form2_nop() %{ 1.2157 + emit_nop(cbuf); 1.2158 + %} 1.2159 + 1.2160 + enc_class form2_illtrap() %{ 1.2161 + emit_illtrap(cbuf); 1.2162 + %} 1.2163 + 1.2164 + 1.2165 + // Compare longs and convert into -1, 0, 1. 1.2166 + enc_class cmpl_flag( iRegL src1, iRegL src2, iRegI dst ) %{ 1.2167 + // CMP $src1,$src2 1.2168 + emit3( cbuf, Assembler::arith_op, 0, Assembler::subcc_op3, $src1$$reg, 0, $src2$$reg ); 1.2169 + // blt,a,pn done 1.2170 + emit2_19( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::less , Assembler::bp_op2, Assembler::xcc, 0/*predict not taken*/, 5 ); 1.2171 + // mov dst,-1 in delay slot 1.2172 + emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, -1 ); 1.2173 + // bgt,a,pn done 1.2174 + emit2_19( cbuf, Assembler::branch_op, 1/*annul*/, Assembler::greater, Assembler::bp_op2, Assembler::xcc, 0/*predict not taken*/, 3 ); 1.2175 + // mov dst,1 in delay slot 1.2176 + emit3_simm13( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3, 0, 1 ); 1.2177 + // CLR $dst 1.2178 + emit3( cbuf, Assembler::arith_op, $dst$$reg, Assembler::or_op3 , 0, 0, 0 ); 1.2179 + %} 1.2180 + 1.2181 + enc_class enc_PartialSubtypeCheck() %{ 1.2182 + MacroAssembler _masm(&cbuf); 1.2183 + __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); 1.2184 + __ delayed()->nop(); 1.2185 + %} 1.2186 + 1.2187 + enc_class enc_bp( Label labl, cmpOp cmp, flagsReg cc ) %{ 1.2188 + MacroAssembler _masm(&cbuf); 1.2189 + Label &L = *($labl$$label); 1.2190 + Assembler::Predict predict_taken = 1.2191 + cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; 1.2192 + 1.2193 + __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, L); 1.2194 + __ delayed()->nop(); 1.2195 + %} 1.2196 + 1.2197 + enc_class enc_bpl( Label labl, cmpOp cmp, flagsRegL cc ) %{ 1.2198 + MacroAssembler _masm(&cbuf); 1.2199 + Label &L = *($labl$$label); 1.2200 + Assembler::Predict predict_taken = 1.2201 + cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; 1.2202 + 1.2203 + __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, L); 1.2204 + __ delayed()->nop(); 1.2205 + %} 1.2206 + 1.2207 + enc_class enc_bpx( Label labl, cmpOp cmp, flagsRegP cc ) %{ 1.2208 + MacroAssembler _masm(&cbuf); 1.2209 + Label &L = *($labl$$label); 1.2210 + Assembler::Predict predict_taken = 1.2211 + cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; 1.2212 + 1.2213 + __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, L); 1.2214 + __ delayed()->nop(); 1.2215 + %} 1.2216 + 1.2217 + enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{ 1.2218 + MacroAssembler _masm(&cbuf); 1.2219 + Label &L = *($labl$$label); 1.2220 + Assembler::Predict predict_taken = 1.2221 + cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; 1.2222 + 1.2223 + __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L); 1.2224 + __ delayed()->nop(); 1.2225 + %} 1.2226 + 1.2227 + enc_class jump_enc( iRegX switch_val, o7RegI table) %{ 1.2228 + MacroAssembler _masm(&cbuf); 1.2229 + 1.2230 + Register switch_reg = as_Register($switch_val$$reg); 1.2231 + Register table_reg = O7; 1.2232 + 1.2233 + address table_base = __ address_table_constant(_index2label); 1.2234 + RelocationHolder rspec = internal_word_Relocation::spec(table_base); 1.2235 + 1.2236 + // Load table address 1.2237 + Address the_pc(table_reg, table_base, rspec); 1.2238 + __ load_address(the_pc); 1.2239 + 1.2240 + // Jump to base address + switch value 1.2241 + __ ld_ptr(table_reg, switch_reg, table_reg); 1.2242 + __ jmp(table_reg, G0); 1.2243 + __ delayed()->nop(); 1.2244 + 1.2245 + %} 1.2246 + 1.2247 + enc_class enc_ba( Label labl ) %{ 1.2248 + MacroAssembler _masm(&cbuf); 1.2249 + Label &L = *($labl$$label); 1.2250 + __ ba(false, L); 1.2251 + __ delayed()->nop(); 1.2252 + %} 1.2253 + 1.2254 + enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{ 1.2255 + MacroAssembler _masm(&cbuf); 1.2256 + Label &L = *$labl$$label; 1.2257 + Assembler::Predict predict_taken = 1.2258 + cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; 1.2259 + 1.2260 + __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), L); 1.2261 + __ delayed()->nop(); 1.2262 + %} 1.2263 + 1.2264 + enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ 1.2265 + int op = (Assembler::arith_op << 30) | 1.2266 + ($dst$$reg << 25) | 1.2267 + (Assembler::movcc_op3 << 19) | 1.2268 + (1 << 18) | // cc2 bit for 'icc' 1.2269 + ($cmp$$cmpcode << 14) | 1.2270 + (0 << 13) | // select register move 1.2271 + ($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' or 'xcc' 1.2272 + ($src$$reg << 0); 1.2273 + *((int*)(cbuf.code_end())) = op; 1.2274 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2275 + %} 1.2276 + 1.2277 + enc_class enc_cmov_imm( cmpOp cmp, iRegI dst, immI11 src, immI pcc ) %{ 1.2278 + int simm11 = $src$$constant & ((1<<11)-1); // Mask to 11 bits 1.2279 + int op = (Assembler::arith_op << 30) | 1.2280 + ($dst$$reg << 25) | 1.2281 + (Assembler::movcc_op3 << 19) | 1.2282 + (1 << 18) | // cc2 bit for 'icc' 1.2283 + ($cmp$$cmpcode << 14) | 1.2284 + (1 << 13) | // select immediate move 1.2285 + ($pcc$$constant << 11) | // cc1, cc0 bits for 'icc' 1.2286 + (simm11 << 0); 1.2287 + *((int*)(cbuf.code_end())) = op; 1.2288 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2289 + %} 1.2290 + 1.2291 + enc_class enc_cmov_reg_f( cmpOpF cmp, iRegI dst, iRegI src, flagsRegF fcc ) %{ 1.2292 + int op = (Assembler::arith_op << 30) | 1.2293 + ($dst$$reg << 25) | 1.2294 + (Assembler::movcc_op3 << 19) | 1.2295 + (0 << 18) | // cc2 bit for 'fccX' 1.2296 + ($cmp$$cmpcode << 14) | 1.2297 + (0 << 13) | // select register move 1.2298 + ($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3 1.2299 + ($src$$reg << 0); 1.2300 + *((int*)(cbuf.code_end())) = op; 1.2301 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2302 + %} 1.2303 + 1.2304 + enc_class enc_cmov_imm_f( cmpOp cmp, iRegI dst, immI11 src, flagsRegF fcc ) %{ 1.2305 + int simm11 = $src$$constant & ((1<<11)-1); // Mask to 11 bits 1.2306 + int op = (Assembler::arith_op << 30) | 1.2307 + ($dst$$reg << 25) | 1.2308 + (Assembler::movcc_op3 << 19) | 1.2309 + (0 << 18) | // cc2 bit for 'fccX' 1.2310 + ($cmp$$cmpcode << 14) | 1.2311 + (1 << 13) | // select immediate move 1.2312 + ($fcc$$reg << 11) | // cc1, cc0 bits for fcc0-fcc3 1.2313 + (simm11 << 0); 1.2314 + *((int*)(cbuf.code_end())) = op; 1.2315 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2316 + %} 1.2317 + 1.2318 + enc_class enc_cmovf_reg( cmpOp cmp, regD dst, regD src, immI pcc ) %{ 1.2319 + int op = (Assembler::arith_op << 30) | 1.2320 + ($dst$$reg << 25) | 1.2321 + (Assembler::fpop2_op3 << 19) | 1.2322 + (0 << 18) | 1.2323 + ($cmp$$cmpcode << 14) | 1.2324 + (1 << 13) | // select register move 1.2325 + ($pcc$$constant << 11) | // cc1-cc0 bits for 'icc' or 'xcc' 1.2326 + ($primary << 5) | // select single, double or quad 1.2327 + ($src$$reg << 0); 1.2328 + *((int*)(cbuf.code_end())) = op; 1.2329 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2330 + %} 1.2331 + 1.2332 + enc_class enc_cmovff_reg( cmpOpF cmp, flagsRegF fcc, regD dst, regD src ) %{ 1.2333 + int op = (Assembler::arith_op << 30) | 1.2334 + ($dst$$reg << 25) | 1.2335 + (Assembler::fpop2_op3 << 19) | 1.2336 + (0 << 18) | 1.2337 + ($cmp$$cmpcode << 14) | 1.2338 + ($fcc$$reg << 11) | // cc2-cc0 bits for 'fccX' 1.2339 + ($primary << 5) | // select single, double or quad 1.2340 + ($src$$reg << 0); 1.2341 + *((int*)(cbuf.code_end())) = op; 1.2342 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2343 + %} 1.2344 + 1.2345 + // Used by the MIN/MAX encodings. Same as a CMOV, but 1.2346 + // the condition comes from opcode-field instead of an argument. 1.2347 + enc_class enc_cmov_reg_minmax( iRegI dst, iRegI src ) %{ 1.2348 + int op = (Assembler::arith_op << 30) | 1.2349 + ($dst$$reg << 25) | 1.2350 + (Assembler::movcc_op3 << 19) | 1.2351 + (1 << 18) | // cc2 bit for 'icc' 1.2352 + ($primary << 14) | 1.2353 + (0 << 13) | // select register move 1.2354 + (0 << 11) | // cc1, cc0 bits for 'icc' 1.2355 + ($src$$reg << 0); 1.2356 + *((int*)(cbuf.code_end())) = op; 1.2357 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2358 + %} 1.2359 + 1.2360 + enc_class enc_cmov_reg_minmax_long( iRegL dst, iRegL src ) %{ 1.2361 + int op = (Assembler::arith_op << 30) | 1.2362 + ($dst$$reg << 25) | 1.2363 + (Assembler::movcc_op3 << 19) | 1.2364 + (6 << 16) | // cc2 bit for 'xcc' 1.2365 + ($primary << 14) | 1.2366 + (0 << 13) | // select register move 1.2367 + (0 << 11) | // cc1, cc0 bits for 'icc' 1.2368 + ($src$$reg << 0); 1.2369 + *((int*)(cbuf.code_end())) = op; 1.2370 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2371 + %} 1.2372 + 1.2373 + // Utility encoding for loading a 64 bit Pointer into a register 1.2374 + // The 64 bit pointer is stored in the generated code stream 1.2375 + enc_class SetPtr( immP src, iRegP rd ) %{ 1.2376 + Register dest = reg_to_register_object($rd$$reg); 1.2377 + // [RGV] This next line should be generated from ADLC 1.2378 + if ( _opnds[1]->constant_is_oop() ) { 1.2379 + intptr_t val = $src$$constant; 1.2380 + MacroAssembler _masm(&cbuf); 1.2381 + __ set_oop_constant((jobject)val, dest); 1.2382 + } else { // non-oop pointers, e.g. card mark base, heap top 1.2383 + emit_ptr(cbuf, $src$$constant, dest, /*ForceRelocatable=*/ false); 1.2384 + } 1.2385 + %} 1.2386 + 1.2387 + enc_class Set13( immI13 src, iRegI rd ) %{ 1.2388 + emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant ); 1.2389 + %} 1.2390 + 1.2391 + enc_class SetHi22( immI src, iRegI rd ) %{ 1.2392 + emit2_22( cbuf, Assembler::branch_op, $rd$$reg, Assembler::sethi_op2, $src$$constant ); 1.2393 + %} 1.2394 + 1.2395 + enc_class Set32( immI src, iRegI rd ) %{ 1.2396 + MacroAssembler _masm(&cbuf); 1.2397 + __ set($src$$constant, reg_to_register_object($rd$$reg)); 1.2398 + %} 1.2399 + 1.2400 + enc_class SetNull( iRegI rd ) %{ 1.2401 + emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 ); 1.2402 + %} 1.2403 + 1.2404 + enc_class call_epilog %{ 1.2405 + if( VerifyStackAtCalls ) { 1.2406 + MacroAssembler _masm(&cbuf); 1.2407 + int framesize = ra_->C->frame_slots() << LogBytesPerInt; 1.2408 + Register temp_reg = G3; 1.2409 + __ add(SP, framesize, temp_reg); 1.2410 + __ cmp(temp_reg, FP); 1.2411 + __ breakpoint_trap(Assembler::notEqual, Assembler::ptr_cc); 1.2412 + } 1.2413 + %} 1.2414 + 1.2415 + // Long values come back from native calls in O0:O1 in the 32-bit VM, copy the value 1.2416 + // to G1 so the register allocator will not have to deal with the misaligned register 1.2417 + // pair. 1.2418 + enc_class adjust_long_from_native_call %{ 1.2419 +#ifndef _LP64 1.2420 + if (returns_long()) { 1.2421 + // sllx O0,32,O0 1.2422 + emit3_simm13( cbuf, Assembler::arith_op, R_O0_enc, Assembler::sllx_op3, R_O0_enc, 0x1020 ); 1.2423 + // srl O1,0,O1 1.2424 + emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::srl_op3, R_O1_enc, 0x0000 ); 1.2425 + // or O0,O1,G1 1.2426 + emit3 ( cbuf, Assembler::arith_op, R_G1_enc, Assembler:: or_op3, R_O0_enc, 0, R_O1_enc ); 1.2427 + } 1.2428 +#endif 1.2429 + %} 1.2430 + 1.2431 + enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime 1.2432 + // CALL directly to the runtime 1.2433 + // The user of this is responsible for ensuring that R_L7 is empty (killed). 1.2434 + emit_call_reloc(cbuf, $meth$$method, relocInfo::runtime_call_type, 1.2435 + /*preserve_g2=*/true, /*force far call*/true); 1.2436 + %} 1.2437 + 1.2438 + enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL 1.2439 + // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1.2440 + // who we intended to call. 1.2441 + if ( !_method ) { 1.2442 + emit_call_reloc(cbuf, $meth$$method, relocInfo::runtime_call_type); 1.2443 + } else if (_optimized_virtual) { 1.2444 + emit_call_reloc(cbuf, $meth$$method, relocInfo::opt_virtual_call_type); 1.2445 + } else { 1.2446 + emit_call_reloc(cbuf, $meth$$method, relocInfo::static_call_type); 1.2447 + } 1.2448 + if( _method ) { // Emit stub for static call 1.2449 + emit_java_to_interp(cbuf); 1.2450 + } 1.2451 + %} 1.2452 + 1.2453 + enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL 1.2454 + MacroAssembler _masm(&cbuf); 1.2455 + __ set_inst_mark(); 1.2456 + int vtable_index = this->_vtable_index; 1.2457 + // MachCallDynamicJavaNode::ret_addr_offset uses this same test 1.2458 + if (vtable_index < 0) { 1.2459 + // must be invalid_vtable_index, not nonvirtual_vtable_index 1.2460 + assert(vtable_index == methodOopDesc::invalid_vtable_index, "correct sentinel value"); 1.2461 + Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); 1.2462 + assert(G5_ic_reg == G5_inline_cache_reg, "G5_inline_cache_reg used in assemble_ic_buffer_code()"); 1.2463 + assert(G5_ic_reg == G5_megamorphic_method, "G5_megamorphic_method used in megamorphic call stub"); 1.2464 + // !!!!! 1.2465 + // Generate "set 0x01, R_G5", placeholder instruction to load oop-info 1.2466 + // emit_call_dynamic_prologue( cbuf ); 1.2467 + __ set_oop((jobject)Universe::non_oop_word(), G5_ic_reg); 1.2468 + 1.2469 + address virtual_call_oop_addr = __ inst_mark(); 1.2470 + // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1.2471 + // who we intended to call. 1.2472 + __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr)); 1.2473 + emit_call_reloc(cbuf, $meth$$method, relocInfo::none); 1.2474 + } else { 1.2475 + assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1.2476 + // Just go thru the vtable 1.2477 + // get receiver klass (receiver already checked for non-null) 1.2478 + // If we end up going thru a c2i adapter interpreter expects method in G5 1.2479 + int off = __ offset(); 1.2480 + __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); 1.2481 + int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); 1.2482 + int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); 1.2483 + if( __ is_simm13(v_off) ) { 1.2484 + __ ld_ptr(G3, v_off, G5_method); 1.2485 + } else { 1.2486 + // Generate 2 instructions 1.2487 + __ Assembler::sethi(v_off & ~0x3ff, G5_method); 1.2488 + __ or3(G5_method, v_off & 0x3ff, G5_method); 1.2489 + // ld_ptr, set_hi, set 1.2490 + assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)"); 1.2491 + __ ld_ptr(G3, G5_method, G5_method); 1.2492 + } 1.2493 + // NOTE: for vtable dispatches, the vtable entry will never be null. 1.2494 + // However it may very well end up in handle_wrong_method if the 1.2495 + // method is abstract for the particular class. 1.2496 + __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch); 1.2497 + // jump to target (either compiled code or c2iadapter) 1.2498 + __ jmpl(G3_scratch, G0, O7); 1.2499 + __ delayed()->nop(); 1.2500 + } 1.2501 + %} 1.2502 + 1.2503 + enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL 1.2504 + MacroAssembler _masm(&cbuf); 1.2505 + 1.2506 + Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); 1.2507 + Register temp_reg = G3; // caller must kill G3! We cannot reuse G5_ic_reg here because 1.2508 + // we might be calling a C2I adapter which needs it. 1.2509 + 1.2510 + assert(temp_reg != G5_ic_reg, "conflicting registers"); 1.2511 + // Load nmethod 1.2512 + __ ld_ptr(G5_ic_reg, in_bytes(methodOopDesc::from_compiled_offset()), temp_reg); 1.2513 + 1.2514 + // CALL to compiled java, indirect the contents of G3 1.2515 + __ set_inst_mark(); 1.2516 + __ callr(temp_reg, G0); 1.2517 + __ delayed()->nop(); 1.2518 + %} 1.2519 + 1.2520 +enc_class idiv_reg(iRegIsafe src1, iRegIsafe src2, iRegIsafe dst) %{ 1.2521 + MacroAssembler _masm(&cbuf); 1.2522 + Register Rdividend = reg_to_register_object($src1$$reg); 1.2523 + Register Rdivisor = reg_to_register_object($src2$$reg); 1.2524 + Register Rresult = reg_to_register_object($dst$$reg); 1.2525 + 1.2526 + __ sra(Rdivisor, 0, Rdivisor); 1.2527 + __ sra(Rdividend, 0, Rdividend); 1.2528 + __ sdivx(Rdividend, Rdivisor, Rresult); 1.2529 +%} 1.2530 + 1.2531 +enc_class idiv_imm(iRegIsafe src1, immI13 imm, iRegIsafe dst) %{ 1.2532 + MacroAssembler _masm(&cbuf); 1.2533 + 1.2534 + Register Rdividend = reg_to_register_object($src1$$reg); 1.2535 + int divisor = $imm$$constant; 1.2536 + Register Rresult = reg_to_register_object($dst$$reg); 1.2537 + 1.2538 + __ sra(Rdividend, 0, Rdividend); 1.2539 + __ sdivx(Rdividend, divisor, Rresult); 1.2540 +%} 1.2541 + 1.2542 +enc_class enc_mul_hi(iRegIsafe dst, iRegIsafe src1, iRegIsafe src2) %{ 1.2543 + MacroAssembler _masm(&cbuf); 1.2544 + Register Rsrc1 = reg_to_register_object($src1$$reg); 1.2545 + Register Rsrc2 = reg_to_register_object($src2$$reg); 1.2546 + Register Rdst = reg_to_register_object($dst$$reg); 1.2547 + 1.2548 + __ sra( Rsrc1, 0, Rsrc1 ); 1.2549 + __ sra( Rsrc2, 0, Rsrc2 ); 1.2550 + __ mulx( Rsrc1, Rsrc2, Rdst ); 1.2551 + __ srlx( Rdst, 32, Rdst ); 1.2552 +%} 1.2553 + 1.2554 +enc_class irem_reg(iRegIsafe src1, iRegIsafe src2, iRegIsafe dst, o7RegL scratch) %{ 1.2555 + MacroAssembler _masm(&cbuf); 1.2556 + Register Rdividend = reg_to_register_object($src1$$reg); 1.2557 + Register Rdivisor = reg_to_register_object($src2$$reg); 1.2558 + Register Rresult = reg_to_register_object($dst$$reg); 1.2559 + Register Rscratch = reg_to_register_object($scratch$$reg); 1.2560 + 1.2561 + assert(Rdividend != Rscratch, ""); 1.2562 + assert(Rdivisor != Rscratch, ""); 1.2563 + 1.2564 + __ sra(Rdividend, 0, Rdividend); 1.2565 + __ sra(Rdivisor, 0, Rdivisor); 1.2566 + __ sdivx(Rdividend, Rdivisor, Rscratch); 1.2567 + __ mulx(Rscratch, Rdivisor, Rscratch); 1.2568 + __ sub(Rdividend, Rscratch, Rresult); 1.2569 +%} 1.2570 + 1.2571 +enc_class irem_imm(iRegIsafe src1, immI13 imm, iRegIsafe dst, o7RegL scratch) %{ 1.2572 + MacroAssembler _masm(&cbuf); 1.2573 + 1.2574 + Register Rdividend = reg_to_register_object($src1$$reg); 1.2575 + int divisor = $imm$$constant; 1.2576 + Register Rresult = reg_to_register_object($dst$$reg); 1.2577 + Register Rscratch = reg_to_register_object($scratch$$reg); 1.2578 + 1.2579 + assert(Rdividend != Rscratch, ""); 1.2580 + 1.2581 + __ sra(Rdividend, 0, Rdividend); 1.2582 + __ sdivx(Rdividend, divisor, Rscratch); 1.2583 + __ mulx(Rscratch, divisor, Rscratch); 1.2584 + __ sub(Rdividend, Rscratch, Rresult); 1.2585 +%} 1.2586 + 1.2587 +enc_class fabss (sflt_reg dst, sflt_reg src) %{ 1.2588 + MacroAssembler _masm(&cbuf); 1.2589 + 1.2590 + FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); 1.2591 + FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); 1.2592 + 1.2593 + __ fabs(FloatRegisterImpl::S, Fsrc, Fdst); 1.2594 +%} 1.2595 + 1.2596 +enc_class fabsd (dflt_reg dst, dflt_reg src) %{ 1.2597 + MacroAssembler _masm(&cbuf); 1.2598 + 1.2599 + FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); 1.2600 + FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); 1.2601 + 1.2602 + __ fabs(FloatRegisterImpl::D, Fsrc, Fdst); 1.2603 +%} 1.2604 + 1.2605 +enc_class fnegd (dflt_reg dst, dflt_reg src) %{ 1.2606 + MacroAssembler _masm(&cbuf); 1.2607 + 1.2608 + FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); 1.2609 + FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); 1.2610 + 1.2611 + __ fneg(FloatRegisterImpl::D, Fsrc, Fdst); 1.2612 +%} 1.2613 + 1.2614 +enc_class fsqrts (sflt_reg dst, sflt_reg src) %{ 1.2615 + MacroAssembler _masm(&cbuf); 1.2616 + 1.2617 + FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); 1.2618 + FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); 1.2619 + 1.2620 + __ fsqrt(FloatRegisterImpl::S, Fsrc, Fdst); 1.2621 +%} 1.2622 + 1.2623 +enc_class fsqrtd (dflt_reg dst, dflt_reg src) %{ 1.2624 + MacroAssembler _masm(&cbuf); 1.2625 + 1.2626 + FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); 1.2627 + FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); 1.2628 + 1.2629 + __ fsqrt(FloatRegisterImpl::D, Fsrc, Fdst); 1.2630 +%} 1.2631 + 1.2632 +enc_class fmovs (dflt_reg dst, dflt_reg src) %{ 1.2633 + MacroAssembler _masm(&cbuf); 1.2634 + 1.2635 + FloatRegister Fdst = reg_to_SingleFloatRegister_object($dst$$reg); 1.2636 + FloatRegister Fsrc = reg_to_SingleFloatRegister_object($src$$reg); 1.2637 + 1.2638 + __ fmov(FloatRegisterImpl::S, Fsrc, Fdst); 1.2639 +%} 1.2640 + 1.2641 +enc_class fmovd (dflt_reg dst, dflt_reg src) %{ 1.2642 + MacroAssembler _masm(&cbuf); 1.2643 + 1.2644 + FloatRegister Fdst = reg_to_DoubleFloatRegister_object($dst$$reg); 1.2645 + FloatRegister Fsrc = reg_to_DoubleFloatRegister_object($src$$reg); 1.2646 + 1.2647 + __ fmov(FloatRegisterImpl::D, Fsrc, Fdst); 1.2648 +%} 1.2649 + 1.2650 +enc_class Fast_Lock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{ 1.2651 + MacroAssembler _masm(&cbuf); 1.2652 + 1.2653 + Register Roop = reg_to_register_object($oop$$reg); 1.2654 + Register Rbox = reg_to_register_object($box$$reg); 1.2655 + Register Rscratch = reg_to_register_object($scratch$$reg); 1.2656 + Register Rmark = reg_to_register_object($scratch2$$reg); 1.2657 + 1.2658 + assert(Roop != Rscratch, ""); 1.2659 + assert(Roop != Rmark, ""); 1.2660 + assert(Rbox != Rscratch, ""); 1.2661 + assert(Rbox != Rmark, ""); 1.2662 + 1.2663 + __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters); 1.2664 +%} 1.2665 + 1.2666 +enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{ 1.2667 + MacroAssembler _masm(&cbuf); 1.2668 + 1.2669 + Register Roop = reg_to_register_object($oop$$reg); 1.2670 + Register Rbox = reg_to_register_object($box$$reg); 1.2671 + Register Rscratch = reg_to_register_object($scratch$$reg); 1.2672 + Register Rmark = reg_to_register_object($scratch2$$reg); 1.2673 + 1.2674 + assert(Roop != Rscratch, ""); 1.2675 + assert(Roop != Rmark, ""); 1.2676 + assert(Rbox != Rscratch, ""); 1.2677 + assert(Rbox != Rmark, ""); 1.2678 + 1.2679 + __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch); 1.2680 + %} 1.2681 + 1.2682 + enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{ 1.2683 + MacroAssembler _masm(&cbuf); 1.2684 + Register Rmem = reg_to_register_object($mem$$reg); 1.2685 + Register Rold = reg_to_register_object($old$$reg); 1.2686 + Register Rnew = reg_to_register_object($new$$reg); 1.2687 + 1.2688 + // casx_under_lock picks 1 of 3 encodings: 1.2689 + // For 32-bit pointers you get a 32-bit CAS 1.2690 + // For 64-bit pointers you get a 64-bit CASX 1.2691 + __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold 1.2692 + (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr()); 1.2693 + __ cmp( Rold, Rnew ); 1.2694 + %} 1.2695 + 1.2696 + enc_class enc_casx( iRegP mem, iRegL old, iRegL new) %{ 1.2697 + Register Rmem = reg_to_register_object($mem$$reg); 1.2698 + Register Rold = reg_to_register_object($old$$reg); 1.2699 + Register Rnew = reg_to_register_object($new$$reg); 1.2700 + 1.2701 + MacroAssembler _masm(&cbuf); 1.2702 + __ mov(Rnew, O7); 1.2703 + __ casx(Rmem, Rold, O7); 1.2704 + __ cmp( Rold, O7 ); 1.2705 + %} 1.2706 + 1.2707 + // raw int cas, used for compareAndSwap 1.2708 + enc_class enc_casi( iRegP mem, iRegL old, iRegL new) %{ 1.2709 + Register Rmem = reg_to_register_object($mem$$reg); 1.2710 + Register Rold = reg_to_register_object($old$$reg); 1.2711 + Register Rnew = reg_to_register_object($new$$reg); 1.2712 + 1.2713 + MacroAssembler _masm(&cbuf); 1.2714 + __ mov(Rnew, O7); 1.2715 + __ cas(Rmem, Rold, O7); 1.2716 + __ cmp( Rold, O7 ); 1.2717 + %} 1.2718 + 1.2719 + enc_class enc_lflags_ne_to_boolean( iRegI res ) %{ 1.2720 + Register Rres = reg_to_register_object($res$$reg); 1.2721 + 1.2722 + MacroAssembler _masm(&cbuf); 1.2723 + __ mov(1, Rres); 1.2724 + __ movcc( Assembler::notEqual, false, Assembler::xcc, G0, Rres ); 1.2725 + %} 1.2726 + 1.2727 + enc_class enc_iflags_ne_to_boolean( iRegI res ) %{ 1.2728 + Register Rres = reg_to_register_object($res$$reg); 1.2729 + 1.2730 + MacroAssembler _masm(&cbuf); 1.2731 + __ mov(1, Rres); 1.2732 + __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); 1.2733 + %} 1.2734 + 1.2735 + enc_class floating_cmp ( iRegP dst, regF src1, regF src2 ) %{ 1.2736 + MacroAssembler _masm(&cbuf); 1.2737 + Register Rdst = reg_to_register_object($dst$$reg); 1.2738 + FloatRegister Fsrc1 = $primary ? reg_to_SingleFloatRegister_object($src1$$reg) 1.2739 + : reg_to_DoubleFloatRegister_object($src1$$reg); 1.2740 + FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg) 1.2741 + : reg_to_DoubleFloatRegister_object($src2$$reg); 1.2742 + 1.2743 + // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) 1.2744 + __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 1.2745 + %} 1.2746 + 1.2747 + enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate 1.2748 + MacroAssembler _masm(&cbuf); 1.2749 + Register dest = reg_to_register_object($dst$$reg); 1.2750 + Register temp = reg_to_register_object($tmp$$reg); 1.2751 + __ set64( $src$$constant, dest, temp ); 1.2752 + %} 1.2753 + 1.2754 + enc_class LdImmF(immF src, regF dst, o7RegP tmp) %{ // Load Immediate 1.2755 + address float_address = MacroAssembler(&cbuf).float_constant($src$$constant); 1.2756 + RelocationHolder rspec = internal_word_Relocation::spec(float_address); 1.2757 +#ifdef _LP64 1.2758 + Register tmp_reg = reg_to_register_object($tmp$$reg); 1.2759 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2760 + emit_ptr(cbuf, (intptr_t)float_address, tmp_reg, /*ForceRelocatable=*/ true); 1.2761 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::ldf_op3, $tmp$$reg, 0 ); 1.2762 +#else // _LP64 1.2763 + uint *code; 1.2764 + int tmp_reg = $tmp$$reg; 1.2765 + 1.2766 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2767 + emit2_22( cbuf, Assembler::branch_op, tmp_reg, Assembler::sethi_op2, (intptr_t) float_address ); 1.2768 + 1.2769 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2770 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::ldf_op3, tmp_reg, (intptr_t) float_address ); 1.2771 +#endif // _LP64 1.2772 + %} 1.2773 + 1.2774 + enc_class LdImmD(immD src, regD dst, o7RegP tmp) %{ // Load Immediate 1.2775 + address double_address = MacroAssembler(&cbuf).double_constant($src$$constant); 1.2776 + RelocationHolder rspec = internal_word_Relocation::spec(double_address); 1.2777 +#ifdef _LP64 1.2778 + Register tmp_reg = reg_to_register_object($tmp$$reg); 1.2779 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2780 + emit_ptr(cbuf, (intptr_t)double_address, tmp_reg, /*ForceRelocatable=*/ true); 1.2781 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::lddf_op3, $tmp$$reg, 0 ); 1.2782 +#else // _LP64 1.2783 + uint *code; 1.2784 + int tmp_reg = $tmp$$reg; 1.2785 + 1.2786 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2787 + emit2_22( cbuf, Assembler::branch_op, tmp_reg, Assembler::sethi_op2, (intptr_t) double_address ); 1.2788 + 1.2789 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2790 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::lddf_op3, tmp_reg, (intptr_t) double_address ); 1.2791 +#endif // _LP64 1.2792 + %} 1.2793 + 1.2794 + enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{ 1.2795 + // Load a constant replicated "count" times with width "width" 1.2796 + int bit_width = $width$$constant * 8; 1.2797 + jlong elt_val = $src$$constant; 1.2798 + elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits 1.2799 + jlong val = elt_val; 1.2800 + for (int i = 0; i < $count$$constant - 1; i++) { 1.2801 + val <<= bit_width; 1.2802 + val |= elt_val; 1.2803 + } 1.2804 + jdouble dval = *(jdouble*)&val; // coerce to double type 1.2805 + address double_address = MacroAssembler(&cbuf).double_constant(dval); 1.2806 + RelocationHolder rspec = internal_word_Relocation::spec(double_address); 1.2807 +#ifdef _LP64 1.2808 + Register tmp_reg = reg_to_register_object($tmp$$reg); 1.2809 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2810 + emit_ptr(cbuf, (intptr_t)double_address, tmp_reg, /*ForceRelocatable=*/ true); 1.2811 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::lddf_op3, $tmp$$reg, 0 ); 1.2812 +#else // _LP64 1.2813 + uint *code; 1.2814 + int tmp_reg = $tmp$$reg; 1.2815 + 1.2816 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2817 + emit2_22( cbuf, Assembler::branch_op, tmp_reg, Assembler::sethi_op2, (intptr_t) double_address ); 1.2818 + 1.2819 + cbuf.relocate(cbuf.code_end(), rspec, 0); 1.2820 + emit3_simm10( cbuf, Assembler::ldst_op, $dst$$reg, Assembler::lddf_op3, tmp_reg, (intptr_t) double_address ); 1.2821 +#endif // _LP64 1.2822 + %} 1.2823 + 1.2824 + 1.2825 + enc_class ShouldNotEncodeThis ( ) %{ 1.2826 + ShouldNotCallThis(); 1.2827 + %} 1.2828 + 1.2829 + // Compiler ensures base is doubleword aligned and cnt is count of doublewords 1.2830 + enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ 1.2831 + MacroAssembler _masm(&cbuf); 1.2832 + Register nof_bytes_arg = reg_to_register_object($cnt$$reg); 1.2833 + Register nof_bytes_tmp = reg_to_register_object($temp$$reg); 1.2834 + Register base_pointer_arg = reg_to_register_object($base$$reg); 1.2835 + 1.2836 + Label loop; 1.2837 + __ mov(nof_bytes_arg, nof_bytes_tmp); 1.2838 + 1.2839 + // Loop and clear, walking backwards through the array. 1.2840 + // nof_bytes_tmp (if >0) is always the number of bytes to zero 1.2841 + __ bind(loop); 1.2842 + __ deccc(nof_bytes_tmp, 8); 1.2843 + __ br(Assembler::greaterEqual, true, Assembler::pt, loop); 1.2844 + __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp); 1.2845 + // %%%% this mini-loop must not cross a cache boundary! 1.2846 + %} 1.2847 + 1.2848 + 1.2849 + enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result) %{ 1.2850 + Label Ldone, Lloop; 1.2851 + MacroAssembler _masm(&cbuf); 1.2852 + 1.2853 + Register str1_reg = reg_to_register_object($str1$$reg); 1.2854 + Register str2_reg = reg_to_register_object($str2$$reg); 1.2855 + Register tmp1_reg = reg_to_register_object($tmp1$$reg); 1.2856 + Register tmp2_reg = reg_to_register_object($tmp2$$reg); 1.2857 + Register result_reg = reg_to_register_object($result$$reg); 1.2858 + 1.2859 + // Get the first character position in both strings 1.2860 + // [8] char array, [12] offset, [16] count 1.2861 + int value_offset = java_lang_String:: value_offset_in_bytes(); 1.2862 + int offset_offset = java_lang_String::offset_offset_in_bytes(); 1.2863 + int count_offset = java_lang_String:: count_offset_in_bytes(); 1.2864 + 1.2865 + // load str1 (jchar*) base address into tmp1_reg 1.2866 + __ ld_ptr(Address(str1_reg, 0, value_offset), tmp1_reg); 1.2867 + __ ld(Address(str1_reg, 0, offset_offset), result_reg); 1.2868 + __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg); 1.2869 + __ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted 1.2870 + __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg); 1.2871 + __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted 1.2872 + __ add(result_reg, tmp1_reg, tmp1_reg); 1.2873 + 1.2874 + // load str2 (jchar*) base address into tmp2_reg 1.2875 + // __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted 1.2876 + __ ld(Address(str2_reg, 0, offset_offset), result_reg); 1.2877 + __ add(tmp2_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp2_reg); 1.2878 + __ ld(Address(str2_reg, 0, count_offset), str2_reg); // hoisted 1.2879 + __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg); 1.2880 + __ subcc(str1_reg, str2_reg, O7); // hoisted 1.2881 + __ add(result_reg, tmp2_reg, tmp2_reg); 1.2882 + 1.2883 + // Compute the minimum of the string lengths(str1_reg) and the 1.2884 + // difference of the string lengths (stack) 1.2885 + 1.2886 + // discard string base pointers, after loading up the lengths 1.2887 + // __ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted 1.2888 + // __ ld(Address(str2_reg, 0, count_offset), str2_reg); // hoisted 1.2889 + 1.2890 + // See if the lengths are different, and calculate min in str1_reg. 1.2891 + // Stash diff in O7 in case we need it for a tie-breaker. 1.2892 + Label Lskip; 1.2893 + // __ subcc(str1_reg, str2_reg, O7); // hoisted 1.2894 + __ sll(str1_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit 1.2895 + __ br(Assembler::greater, true, Assembler::pt, Lskip); 1.2896 + // str2 is shorter, so use its count: 1.2897 + __ delayed()->sll(str2_reg, exact_log2(sizeof(jchar)), str1_reg); // scale the limit 1.2898 + __ bind(Lskip); 1.2899 + 1.2900 + // reallocate str1_reg, str2_reg, result_reg 1.2901 + // Note: limit_reg holds the string length pre-scaled by 2 1.2902 + Register limit_reg = str1_reg; 1.2903 + Register chr2_reg = str2_reg; 1.2904 + Register chr1_reg = result_reg; 1.2905 + // tmp{12} are the base pointers 1.2906 + 1.2907 + // Is the minimum length zero? 1.2908 + __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity 1.2909 + __ br(Assembler::equal, true, Assembler::pn, Ldone); 1.2910 + __ delayed()->mov(O7, result_reg); // result is difference in lengths 1.2911 + 1.2912 + // Load first characters 1.2913 + __ lduh(tmp1_reg, 0, chr1_reg); 1.2914 + __ lduh(tmp2_reg, 0, chr2_reg); 1.2915 + 1.2916 + // Compare first characters 1.2917 + __ subcc(chr1_reg, chr2_reg, chr1_reg); 1.2918 + __ br(Assembler::notZero, false, Assembler::pt, Ldone); 1.2919 + assert(chr1_reg == result_reg, "result must be pre-placed"); 1.2920 + __ delayed()->nop(); 1.2921 + 1.2922 + { 1.2923 + // Check after comparing first character to see if strings are equivalent 1.2924 + Label LSkip2; 1.2925 + // Check if the strings start at same location 1.2926 + __ cmp(tmp1_reg, tmp2_reg); 1.2927 + __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2); 1.2928 + __ delayed()->nop(); 1.2929 + 1.2930 + // Check if the length difference is zero (in O7) 1.2931 + __ cmp(G0, O7); 1.2932 + __ br(Assembler::equal, true, Assembler::pn, Ldone); 1.2933 + __ delayed()->mov(G0, result_reg); // result is zero 1.2934 + 1.2935 + // Strings might not be equal 1.2936 + __ bind(LSkip2); 1.2937 + } 1.2938 + 1.2939 + __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg); 1.2940 + __ br(Assembler::equal, true, Assembler::pn, Ldone); 1.2941 + __ delayed()->mov(O7, result_reg); // result is difference in lengths 1.2942 + 1.2943 + // Shift tmp1_reg and tmp2_reg to the end of the arrays, negate limit 1.2944 + __ add(tmp1_reg, limit_reg, tmp1_reg); 1.2945 + __ add(tmp2_reg, limit_reg, tmp2_reg); 1.2946 + __ neg(chr1_reg, limit_reg); // limit = -(limit-2) 1.2947 + 1.2948 + // Compare the rest of the characters 1.2949 + __ lduh(tmp1_reg, limit_reg, chr1_reg); 1.2950 + __ bind(Lloop); 1.2951 + // __ lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted 1.2952 + __ lduh(tmp2_reg, limit_reg, chr2_reg); 1.2953 + __ subcc(chr1_reg, chr2_reg, chr1_reg); 1.2954 + __ br(Assembler::notZero, false, Assembler::pt, Ldone); 1.2955 + assert(chr1_reg == result_reg, "result must be pre-placed"); 1.2956 + __ delayed()->inccc(limit_reg, sizeof(jchar)); 1.2957 + // annul LDUH if branch is not taken to prevent access past end of string 1.2958 + __ br(Assembler::notZero, true, Assembler::pt, Lloop); 1.2959 + __ delayed()->lduh(tmp1_reg, limit_reg, chr1_reg); // hoisted 1.2960 + 1.2961 + // If strings are equal up to min length, return the length difference. 1.2962 + __ mov(O7, result_reg); 1.2963 + 1.2964 + // Otherwise, return the difference between the first mismatched chars. 1.2965 + __ bind(Ldone); 1.2966 + %} 1.2967 + 1.2968 + enc_class enc_rethrow() %{ 1.2969 + cbuf.set_inst_mark(); 1.2970 + Register temp_reg = G3; 1.2971 + Address rethrow_stub(temp_reg, OptoRuntime::rethrow_stub()); 1.2972 + assert(temp_reg != reg_to_register_object(R_I0_num), "temp must not break oop_reg"); 1.2973 + MacroAssembler _masm(&cbuf); 1.2974 +#ifdef ASSERT 1.2975 + __ save_frame(0); 1.2976 + Address last_rethrow_addr(L1, (address)&last_rethrow); 1.2977 + __ sethi(last_rethrow_addr); 1.2978 + __ get_pc(L2); 1.2979 + __ inc(L2, 3 * BytesPerInstWord); // skip this & 2 more insns to point at jump_to 1.2980 + __ st_ptr(L2, last_rethrow_addr); 1.2981 + __ restore(); 1.2982 +#endif 1.2983 + __ JUMP(rethrow_stub, 0); // sethi;jmp 1.2984 + __ delayed()->nop(); 1.2985 + %} 1.2986 + 1.2987 + enc_class emit_mem_nop() %{ 1.2988 + // Generates the instruction LDUXA [o6,g0],#0x82,g0 1.2989 + unsigned int *code = (unsigned int*)cbuf.code_end(); 1.2990 + *code = (unsigned int)0xc0839040; 1.2991 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2992 + %} 1.2993 + 1.2994 + enc_class emit_fadd_nop() %{ 1.2995 + // Generates the instruction FMOVS f31,f31 1.2996 + unsigned int *code = (unsigned int*)cbuf.code_end(); 1.2997 + *code = (unsigned int)0xbfa0003f; 1.2998 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.2999 + %} 1.3000 + 1.3001 + enc_class emit_br_nop() %{ 1.3002 + // Generates the instruction BPN,PN . 1.3003 + unsigned int *code = (unsigned int*)cbuf.code_end(); 1.3004 + *code = (unsigned int)0x00400000; 1.3005 + cbuf.set_code_end(cbuf.code_end() + BytesPerInstWord); 1.3006 + %} 1.3007 + 1.3008 + enc_class enc_membar_acquire %{ 1.3009 + MacroAssembler _masm(&cbuf); 1.3010 + __ membar( Assembler::Membar_mask_bits(Assembler::LoadStore | Assembler::LoadLoad) ); 1.3011 + %} 1.3012 + 1.3013 + enc_class enc_membar_release %{ 1.3014 + MacroAssembler _masm(&cbuf); 1.3015 + __ membar( Assembler::Membar_mask_bits(Assembler::LoadStore | Assembler::StoreStore) ); 1.3016 + %} 1.3017 + 1.3018 + enc_class enc_membar_volatile %{ 1.3019 + MacroAssembler _masm(&cbuf); 1.3020 + __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); 1.3021 + %} 1.3022 + enc_class enc_repl8b( iRegI src, iRegL dst ) %{ 1.3023 + MacroAssembler _masm(&cbuf); 1.3024 + Register src_reg = reg_to_register_object($src$$reg); 1.3025 + Register dst_reg = reg_to_register_object($dst$$reg); 1.3026 + __ sllx(src_reg, 56, dst_reg); 1.3027 + __ srlx(dst_reg, 8, O7); 1.3028 + __ or3 (dst_reg, O7, dst_reg); 1.3029 + __ srlx(dst_reg, 16, O7); 1.3030 + __ or3 (dst_reg, O7, dst_reg); 1.3031 + __ srlx(dst_reg, 32, O7); 1.3032 + __ or3 (dst_reg, O7, dst_reg); 1.3033 + %} 1.3034 + 1.3035 + enc_class enc_repl4b( iRegI src, iRegL dst ) %{ 1.3036 + MacroAssembler _masm(&cbuf); 1.3037 + Register src_reg = reg_to_register_object($src$$reg); 1.3038 + Register dst_reg = reg_to_register_object($dst$$reg); 1.3039 + __ sll(src_reg, 24, dst_reg); 1.3040 + __ srl(dst_reg, 8, O7); 1.3041 + __ or3(dst_reg, O7, dst_reg); 1.3042 + __ srl(dst_reg, 16, O7); 1.3043 + __ or3(dst_reg, O7, dst_reg); 1.3044 + %} 1.3045 + 1.3046 + enc_class enc_repl4s( iRegI src, iRegL dst ) %{ 1.3047 + MacroAssembler _masm(&cbuf); 1.3048 + Register src_reg = reg_to_register_object($src$$reg); 1.3049 + Register dst_reg = reg_to_register_object($dst$$reg); 1.3050 + __ sllx(src_reg, 48, dst_reg); 1.3051 + __ srlx(dst_reg, 16, O7); 1.3052 + __ or3 (dst_reg, O7, dst_reg); 1.3053 + __ srlx(dst_reg, 32, O7); 1.3054 + __ or3 (dst_reg, O7, dst_reg); 1.3055 + %} 1.3056 + 1.3057 + enc_class enc_repl2i( iRegI src, iRegL dst ) %{ 1.3058 + MacroAssembler _masm(&cbuf); 1.3059 + Register src_reg = reg_to_register_object($src$$reg); 1.3060 + Register dst_reg = reg_to_register_object($dst$$reg); 1.3061 + __ sllx(src_reg, 32, dst_reg); 1.3062 + __ srlx(dst_reg, 32, O7); 1.3063 + __ or3 (dst_reg, O7, dst_reg); 1.3064 + %} 1.3065 + 1.3066 +%} 1.3067 + 1.3068 +//----------FRAME-------------------------------------------------------------- 1.3069 +// Definition of frame structure and management information. 1.3070 +// 1.3071 +// S T A C K L A Y O U T Allocators stack-slot number 1.3072 +// | (to get allocators register number 1.3073 +// G Owned by | | v add VMRegImpl::stack0) 1.3074 +// r CALLER | | 1.3075 +// o | +--------+ pad to even-align allocators stack-slot 1.3076 +// w V | pad0 | numbers; owned by CALLER 1.3077 +// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1.3078 +// h ^ | in | 5 1.3079 +// | | args | 4 Holes in incoming args owned by SELF 1.3080 +// | | | | 3 1.3081 +// | | +--------+ 1.3082 +// V | | old out| Empty on Intel, window on Sparc 1.3083 +// | old |preserve| Must be even aligned. 1.3084 +// | SP-+--------+----> Matcher::_old_SP, 8 (or 16 in LP64)-byte aligned 1.3085 +// | | in | 3 area for Intel ret address 1.3086 +// Owned by |preserve| Empty on Sparc. 1.3087 +// SELF +--------+ 1.3088 +// | | pad2 | 2 pad to align old SP 1.3089 +// | +--------+ 1 1.3090 +// | | locks | 0 1.3091 +// | +--------+----> VMRegImpl::stack0, 8 (or 16 in LP64)-byte aligned 1.3092 +// | | pad1 | 11 pad to align new SP 1.3093 +// | +--------+ 1.3094 +// | | | 10 1.3095 +// | | spills | 9 spills 1.3096 +// V | | 8 (pad0 slot for callee) 1.3097 +// -----------+--------+----> Matcher::_out_arg_limit, unaligned 1.3098 +// ^ | out | 7 1.3099 +// | | args | 6 Holes in outgoing args owned by CALLEE 1.3100 +// Owned by +--------+ 1.3101 +// CALLEE | new out| 6 Empty on Intel, window on Sparc 1.3102 +// | new |preserve| Must be even-aligned. 1.3103 +// | SP-+--------+----> Matcher::_new_SP, even aligned 1.3104 +// | | | 1.3105 +// 1.3106 +// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1.3107 +// known from SELF's arguments and the Java calling convention. 1.3108 +// Region 6-7 is determined per call site. 1.3109 +// Note 2: If the calling convention leaves holes in the incoming argument 1.3110 +// area, those holes are owned by SELF. Holes in the outgoing area 1.3111 +// are owned by the CALLEE. Holes should not be nessecary in the 1.3112 +// incoming area, as the Java calling convention is completely under 1.3113 +// the control of the AD file. Doubles can be sorted and packed to 1.3114 +// avoid holes. Holes in the outgoing arguments may be nessecary for 1.3115 +// varargs C calling conventions. 1.3116 +// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1.3117 +// even aligned with pad0 as needed. 1.3118 +// Region 6 is even aligned. Region 6-7 is NOT even aligned; 1.3119 +// region 6-11 is even aligned; it may be padded out more so that 1.3120 +// the region from SP to FP meets the minimum stack alignment. 1.3121 + 1.3122 +frame %{ 1.3123 + // What direction does stack grow in (assumed to be same for native & Java) 1.3124 + stack_direction(TOWARDS_LOW); 1.3125 + 1.3126 + // These two registers define part of the calling convention 1.3127 + // between compiled code and the interpreter. 1.3128 + inline_cache_reg(R_G5); // Inline Cache Register or methodOop for I2C 1.3129 + interpreter_method_oop_reg(R_G5); // Method Oop Register when calling interpreter 1.3130 + 1.3131 + // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] 1.3132 + cisc_spilling_operand_name(indOffset); 1.3133 + 1.3134 + // Number of stack slots consumed by a Monitor enter 1.3135 +#ifdef _LP64 1.3136 + sync_stack_slots(2); 1.3137 +#else 1.3138 + sync_stack_slots(1); 1.3139 +#endif 1.3140 + 1.3141 + // Compiled code's Frame Pointer 1.3142 + frame_pointer(R_SP); 1.3143 + 1.3144 + // Stack alignment requirement 1.3145 + stack_alignment(StackAlignmentInBytes); 1.3146 + // LP64: Alignment size in bytes (128-bit -> 16 bytes) 1.3147 + // !LP64: Alignment size in bytes (64-bit -> 8 bytes) 1.3148 + 1.3149 + // Number of stack slots between incoming argument block and the start of 1.3150 + // a new frame. The PROLOG must add this many slots to the stack. The 1.3151 + // EPILOG must remove this many slots. 1.3152 + in_preserve_stack_slots(0); 1.3153 + 1.3154 + // Number of outgoing stack slots killed above the out_preserve_stack_slots 1.3155 + // for calls to C. Supports the var-args backing area for register parms. 1.3156 + // ADLC doesn't support parsing expressions, so I folded the math by hand. 1.3157 +#ifdef _LP64 1.3158 + // (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (0)) * 2-stack-slots-per-word 1.3159 + varargs_C_out_slots_killed(12); 1.3160 +#else 1.3161 + // (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (1)) * 1-stack-slots-per-word 1.3162 + varargs_C_out_slots_killed( 7); 1.3163 +#endif 1.3164 + 1.3165 + // The after-PROLOG location of the return address. Location of 1.3166 + // return address specifies a type (REG or STACK) and a number 1.3167 + // representing the register number (i.e. - use a register name) or 1.3168 + // stack slot. 1.3169 + return_addr(REG R_I7); // Ret Addr is in register I7 1.3170 + 1.3171 + // Body of function which returns an OptoRegs array locating 1.3172 + // arguments either in registers or in stack slots for calling 1.3173 + // java 1.3174 + calling_convention %{ 1.3175 + (void) SharedRuntime::java_calling_convention(sig_bt, regs, length, is_outgoing); 1.3176 + 1.3177 + %} 1.3178 + 1.3179 + // Body of function which returns an OptoRegs array locating 1.3180 + // arguments either in registers or in stack slots for callin 1.3181 + // C. 1.3182 + c_calling_convention %{ 1.3183 + // This is obviously always outgoing 1.3184 + (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 1.3185 + %} 1.3186 + 1.3187 + // Location of native (C/C++) and interpreter return values. This is specified to 1.3188 + // be the same as Java. In the 32-bit VM, long values are actually returned from 1.3189 + // native calls in O0:O1 and returned to the interpreter in I0:I1. The copying 1.3190 + // to and from the register pairs is done by the appropriate call and epilog 1.3191 + // opcodes. This simplifies the register allocator. 1.3192 + c_return_value %{ 1.3193 + assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 1.3194 +#ifdef _LP64 1.3195 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; 1.3196 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; 1.3197 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; 1.3198 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; 1.3199 +#else // !_LP64 1.3200 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; 1.3201 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.3202 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; 1.3203 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.3204 +#endif 1.3205 + return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 1.3206 + (is_outgoing?lo_out:lo_in)[ideal_reg] ); 1.3207 + %} 1.3208 + 1.3209 + // Location of compiled Java return values. Same as C 1.3210 + return_value %{ 1.3211 + assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 1.3212 +#ifdef _LP64 1.3213 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; 1.3214 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; 1.3215 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; 1.3216 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; 1.3217 +#else // !_LP64 1.3218 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; 1.3219 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.3220 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; 1.3221 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.3222 +#endif 1.3223 + return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 1.3224 + (is_outgoing?lo_out:lo_in)[ideal_reg] ); 1.3225 + %} 1.3226 + 1.3227 +%} 1.3228 + 1.3229 + 1.3230 +//----------ATTRIBUTES--------------------------------------------------------- 1.3231 +//----------Operand Attributes------------------------------------------------- 1.3232 +op_attrib op_cost(1); // Required cost attribute 1.3233 + 1.3234 +//----------Instruction Attributes--------------------------------------------- 1.3235 +ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute 1.3236 +ins_attrib ins_size(32); // Required size attribute (in bits) 1.3237 +ins_attrib ins_pc_relative(0); // Required PC Relative flag 1.3238 +ins_attrib ins_short_branch(0); // Required flag: is this instruction a 1.3239 + // non-matching short branch variant of some 1.3240 + // long branch? 1.3241 + 1.3242 +//----------OPERANDS----------------------------------------------------------- 1.3243 +// Operand definitions must precede instruction definitions for correct parsing 1.3244 +// in the ADLC because operands constitute user defined types which are used in 1.3245 +// instruction definitions. 1.3246 + 1.3247 +//----------Simple Operands---------------------------------------------------- 1.3248 +// Immediate Operands 1.3249 +// Integer Immediate: 32-bit 1.3250 +operand immI() %{ 1.3251 + match(ConI); 1.3252 + 1.3253 + op_cost(0); 1.3254 + // formats are generated automatically for constants and base registers 1.3255 + format %{ %} 1.3256 + interface(CONST_INTER); 1.3257 +%} 1.3258 + 1.3259 +// Integer Immediate: 13-bit 1.3260 +operand immI13() %{ 1.3261 + predicate(Assembler::is_simm13(n->get_int())); 1.3262 + match(ConI); 1.3263 + op_cost(0); 1.3264 + 1.3265 + format %{ %} 1.3266 + interface(CONST_INTER); 1.3267 +%} 1.3268 + 1.3269 +// Unsigned (positive) Integer Immediate: 13-bit 1.3270 +operand immU13() %{ 1.3271 + predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int())); 1.3272 + match(ConI); 1.3273 + op_cost(0); 1.3274 + 1.3275 + format %{ %} 1.3276 + interface(CONST_INTER); 1.3277 +%} 1.3278 + 1.3279 +// Integer Immediate: 6-bit 1.3280 +operand immU6() %{ 1.3281 + predicate(n->get_int() >= 0 && n->get_int() <= 63); 1.3282 + match(ConI); 1.3283 + op_cost(0); 1.3284 + format %{ %} 1.3285 + interface(CONST_INTER); 1.3286 +%} 1.3287 + 1.3288 +// Integer Immediate: 11-bit 1.3289 +operand immI11() %{ 1.3290 + predicate(Assembler::is_simm(n->get_int(),11)); 1.3291 + match(ConI); 1.3292 + op_cost(0); 1.3293 + format %{ %} 1.3294 + interface(CONST_INTER); 1.3295 +%} 1.3296 + 1.3297 +// Integer Immediate: 0-bit 1.3298 +operand immI0() %{ 1.3299 + predicate(n->get_int() == 0); 1.3300 + match(ConI); 1.3301 + op_cost(0); 1.3302 + 1.3303 + format %{ %} 1.3304 + interface(CONST_INTER); 1.3305 +%} 1.3306 + 1.3307 +// Integer Immediate: the value 10 1.3308 +operand immI10() %{ 1.3309 + predicate(n->get_int() == 10); 1.3310 + match(ConI); 1.3311 + op_cost(0); 1.3312 + 1.3313 + format %{ %} 1.3314 + interface(CONST_INTER); 1.3315 +%} 1.3316 + 1.3317 +// Integer Immediate: the values 0-31 1.3318 +operand immU5() %{ 1.3319 + predicate(n->get_int() >= 0 && n->get_int() <= 31); 1.3320 + match(ConI); 1.3321 + op_cost(0); 1.3322 + 1.3323 + format %{ %} 1.3324 + interface(CONST_INTER); 1.3325 +%} 1.3326 + 1.3327 +// Integer Immediate: the values 1-31 1.3328 +operand immI_1_31() %{ 1.3329 + predicate(n->get_int() >= 1 && n->get_int() <= 31); 1.3330 + match(ConI); 1.3331 + op_cost(0); 1.3332 + 1.3333 + format %{ %} 1.3334 + interface(CONST_INTER); 1.3335 +%} 1.3336 + 1.3337 +// Integer Immediate: the values 32-63 1.3338 +operand immI_32_63() %{ 1.3339 + predicate(n->get_int() >= 32 && n->get_int() <= 63); 1.3340 + match(ConI); 1.3341 + op_cost(0); 1.3342 + 1.3343 + format %{ %} 1.3344 + interface(CONST_INTER); 1.3345 +%} 1.3346 + 1.3347 +// Integer Immediate: the value 255 1.3348 +operand immI_255() %{ 1.3349 + predicate( n->get_int() == 255 ); 1.3350 + match(ConI); 1.3351 + op_cost(0); 1.3352 + 1.3353 + format %{ %} 1.3354 + interface(CONST_INTER); 1.3355 +%} 1.3356 + 1.3357 +// Long Immediate: the value FF 1.3358 +operand immL_FF() %{ 1.3359 + predicate( n->get_long() == 0xFFL ); 1.3360 + match(ConL); 1.3361 + op_cost(0); 1.3362 + 1.3363 + format %{ %} 1.3364 + interface(CONST_INTER); 1.3365 +%} 1.3366 + 1.3367 +// Long Immediate: the value FFFF 1.3368 +operand immL_FFFF() %{ 1.3369 + predicate( n->get_long() == 0xFFFFL ); 1.3370 + match(ConL); 1.3371 + op_cost(0); 1.3372 + 1.3373 + format %{ %} 1.3374 + interface(CONST_INTER); 1.3375 +%} 1.3376 + 1.3377 +// Pointer Immediate: 32 or 64-bit 1.3378 +operand immP() %{ 1.3379 + match(ConP); 1.3380 + 1.3381 + op_cost(5); 1.3382 + // formats are generated automatically for constants and base registers 1.3383 + format %{ %} 1.3384 + interface(CONST_INTER); 1.3385 +%} 1.3386 + 1.3387 +operand immP13() %{ 1.3388 + predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095)); 1.3389 + match(ConP); 1.3390 + op_cost(0); 1.3391 + 1.3392 + format %{ %} 1.3393 + interface(CONST_INTER); 1.3394 +%} 1.3395 + 1.3396 +operand immP0() %{ 1.3397 + predicate(n->get_ptr() == 0); 1.3398 + match(ConP); 1.3399 + op_cost(0); 1.3400 + 1.3401 + format %{ %} 1.3402 + interface(CONST_INTER); 1.3403 +%} 1.3404 + 1.3405 +operand immP_poll() %{ 1.3406 + predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); 1.3407 + match(ConP); 1.3408 + 1.3409 + // formats are generated automatically for constants and base registers 1.3410 + format %{ %} 1.3411 + interface(CONST_INTER); 1.3412 +%} 1.3413 + 1.3414 +operand immL() %{ 1.3415 + match(ConL); 1.3416 + op_cost(40); 1.3417 + // formats are generated automatically for constants and base registers 1.3418 + format %{ %} 1.3419 + interface(CONST_INTER); 1.3420 +%} 1.3421 + 1.3422 +operand immL0() %{ 1.3423 + predicate(n->get_long() == 0L); 1.3424 + match(ConL); 1.3425 + op_cost(0); 1.3426 + // formats are generated automatically for constants and base registers 1.3427 + format %{ %} 1.3428 + interface(CONST_INTER); 1.3429 +%} 1.3430 + 1.3431 +// Long Immediate: 13-bit 1.3432 +operand immL13() %{ 1.3433 + predicate((-4096L < n->get_long()) && (n->get_long() <= 4095L)); 1.3434 + match(ConL); 1.3435 + op_cost(0); 1.3436 + 1.3437 + format %{ %} 1.3438 + interface(CONST_INTER); 1.3439 +%} 1.3440 + 1.3441 +// Long Immediate: low 32-bit mask 1.3442 +operand immL_32bits() %{ 1.3443 + predicate(n->get_long() == 0xFFFFFFFFL); 1.3444 + match(ConL); 1.3445 + op_cost(0); 1.3446 + 1.3447 + format %{ %} 1.3448 + interface(CONST_INTER); 1.3449 +%} 1.3450 + 1.3451 +// Double Immediate 1.3452 +operand immD() %{ 1.3453 + match(ConD); 1.3454 + 1.3455 + op_cost(40); 1.3456 + format %{ %} 1.3457 + interface(CONST_INTER); 1.3458 +%} 1.3459 + 1.3460 +operand immD0() %{ 1.3461 +#ifdef _LP64 1.3462 + // on 64-bit architectures this comparision is faster 1.3463 + predicate(jlong_cast(n->getd()) == 0); 1.3464 +#else 1.3465 + predicate((n->getd() == 0) && (fpclass(n->getd()) == FP_PZERO)); 1.3466 +#endif 1.3467 + match(ConD); 1.3468 + 1.3469 + op_cost(0); 1.3470 + format %{ %} 1.3471 + interface(CONST_INTER); 1.3472 +%} 1.3473 + 1.3474 +// Float Immediate 1.3475 +operand immF() %{ 1.3476 + match(ConF); 1.3477 + 1.3478 + op_cost(20); 1.3479 + format %{ %} 1.3480 + interface(CONST_INTER); 1.3481 +%} 1.3482 + 1.3483 +// Float Immediate: 0 1.3484 +operand immF0() %{ 1.3485 + predicate((n->getf() == 0) && (fpclass(n->getf()) == FP_PZERO)); 1.3486 + match(ConF); 1.3487 + 1.3488 + op_cost(0); 1.3489 + format %{ %} 1.3490 + interface(CONST_INTER); 1.3491 +%} 1.3492 + 1.3493 +// Integer Register Operands 1.3494 +// Integer Register 1.3495 +operand iRegI() %{ 1.3496 + constraint(ALLOC_IN_RC(int_reg)); 1.3497 + match(RegI); 1.3498 + 1.3499 + match(notemp_iRegI); 1.3500 + match(g1RegI); 1.3501 + match(o0RegI); 1.3502 + match(iRegIsafe); 1.3503 + 1.3504 + format %{ %} 1.3505 + interface(REG_INTER); 1.3506 +%} 1.3507 + 1.3508 +operand notemp_iRegI() %{ 1.3509 + constraint(ALLOC_IN_RC(notemp_int_reg)); 1.3510 + match(RegI); 1.3511 + 1.3512 + match(o0RegI); 1.3513 + 1.3514 + format %{ %} 1.3515 + interface(REG_INTER); 1.3516 +%} 1.3517 + 1.3518 +operand o0RegI() %{ 1.3519 + constraint(ALLOC_IN_RC(o0_regI)); 1.3520 + match(iRegI); 1.3521 + 1.3522 + format %{ %} 1.3523 + interface(REG_INTER); 1.3524 +%} 1.3525 + 1.3526 +// Pointer Register 1.3527 +operand iRegP() %{ 1.3528 + constraint(ALLOC_IN_RC(ptr_reg)); 1.3529 + match(RegP); 1.3530 + 1.3531 + match(lock_ptr_RegP); 1.3532 + match(g1RegP); 1.3533 + match(g2RegP); 1.3534 + match(g3RegP); 1.3535 + match(g4RegP); 1.3536 + match(i0RegP); 1.3537 + match(o0RegP); 1.3538 + match(o1RegP); 1.3539 + match(l7RegP); 1.3540 + 1.3541 + format %{ %} 1.3542 + interface(REG_INTER); 1.3543 +%} 1.3544 + 1.3545 +operand sp_ptr_RegP() %{ 1.3546 + constraint(ALLOC_IN_RC(sp_ptr_reg)); 1.3547 + match(RegP); 1.3548 + match(iRegP); 1.3549 + 1.3550 + format %{ %} 1.3551 + interface(REG_INTER); 1.3552 +%} 1.3553 + 1.3554 +operand lock_ptr_RegP() %{ 1.3555 + constraint(ALLOC_IN_RC(lock_ptr_reg)); 1.3556 + match(RegP); 1.3557 + match(i0RegP); 1.3558 + match(o0RegP); 1.3559 + match(o1RegP); 1.3560 + match(l7RegP); 1.3561 + 1.3562 + format %{ %} 1.3563 + interface(REG_INTER); 1.3564 +%} 1.3565 + 1.3566 +operand g1RegP() %{ 1.3567 + constraint(ALLOC_IN_RC(g1_regP)); 1.3568 + match(iRegP); 1.3569 + 1.3570 + format %{ %} 1.3571 + interface(REG_INTER); 1.3572 +%} 1.3573 + 1.3574 +operand g2RegP() %{ 1.3575 + constraint(ALLOC_IN_RC(g2_regP)); 1.3576 + match(iRegP); 1.3577 + 1.3578 + format %{ %} 1.3579 + interface(REG_INTER); 1.3580 +%} 1.3581 + 1.3582 +operand g3RegP() %{ 1.3583 + constraint(ALLOC_IN_RC(g3_regP)); 1.3584 + match(iRegP); 1.3585 + 1.3586 + format %{ %} 1.3587 + interface(REG_INTER); 1.3588 +%} 1.3589 + 1.3590 +operand g1RegI() %{ 1.3591 + constraint(ALLOC_IN_RC(g1_regI)); 1.3592 + match(iRegI); 1.3593 + 1.3594 + format %{ %} 1.3595 + interface(REG_INTER); 1.3596 +%} 1.3597 + 1.3598 +operand g3RegI() %{ 1.3599 + constraint(ALLOC_IN_RC(g3_regI)); 1.3600 + match(iRegI); 1.3601 + 1.3602 + format %{ %} 1.3603 + interface(REG_INTER); 1.3604 +%} 1.3605 + 1.3606 +operand g4RegI() %{ 1.3607 + constraint(ALLOC_IN_RC(g4_regI)); 1.3608 + match(iRegI); 1.3609 + 1.3610 + format %{ %} 1.3611 + interface(REG_INTER); 1.3612 +%} 1.3613 + 1.3614 +operand g4RegP() %{ 1.3615 + constraint(ALLOC_IN_RC(g4_regP)); 1.3616 + match(iRegP); 1.3617 + 1.3618 + format %{ %} 1.3619 + interface(REG_INTER); 1.3620 +%} 1.3621 + 1.3622 +operand i0RegP() %{ 1.3623 + constraint(ALLOC_IN_RC(i0_regP)); 1.3624 + match(iRegP); 1.3625 + 1.3626 + format %{ %} 1.3627 + interface(REG_INTER); 1.3628 +%} 1.3629 + 1.3630 +operand o0RegP() %{ 1.3631 + constraint(ALLOC_IN_RC(o0_regP)); 1.3632 + match(iRegP); 1.3633 + 1.3634 + format %{ %} 1.3635 + interface(REG_INTER); 1.3636 +%} 1.3637 + 1.3638 +operand o1RegP() %{ 1.3639 + constraint(ALLOC_IN_RC(o1_regP)); 1.3640 + match(iRegP); 1.3641 + 1.3642 + format %{ %} 1.3643 + interface(REG_INTER); 1.3644 +%} 1.3645 + 1.3646 +operand o2RegP() %{ 1.3647 + constraint(ALLOC_IN_RC(o2_regP)); 1.3648 + match(iRegP); 1.3649 + 1.3650 + format %{ %} 1.3651 + interface(REG_INTER); 1.3652 +%} 1.3653 + 1.3654 +operand o7RegP() %{ 1.3655 + constraint(ALLOC_IN_RC(o7_regP)); 1.3656 + match(iRegP); 1.3657 + 1.3658 + format %{ %} 1.3659 + interface(REG_INTER); 1.3660 +%} 1.3661 + 1.3662 +operand l7RegP() %{ 1.3663 + constraint(ALLOC_IN_RC(l7_regP)); 1.3664 + match(iRegP); 1.3665 + 1.3666 + format %{ %} 1.3667 + interface(REG_INTER); 1.3668 +%} 1.3669 + 1.3670 +operand o7RegI() %{ 1.3671 + constraint(ALLOC_IN_RC(o7_regI)); 1.3672 + match(iRegI); 1.3673 + 1.3674 + format %{ %} 1.3675 + interface(REG_INTER); 1.3676 +%} 1.3677 + 1.3678 +// Long Register 1.3679 +operand iRegL() %{ 1.3680 + constraint(ALLOC_IN_RC(long_reg)); 1.3681 + match(RegL); 1.3682 + 1.3683 + format %{ %} 1.3684 + interface(REG_INTER); 1.3685 +%} 1.3686 + 1.3687 +operand o2RegL() %{ 1.3688 + constraint(ALLOC_IN_RC(o2_regL)); 1.3689 + match(iRegL); 1.3690 + 1.3691 + format %{ %} 1.3692 + interface(REG_INTER); 1.3693 +%} 1.3694 + 1.3695 +operand o7RegL() %{ 1.3696 + constraint(ALLOC_IN_RC(o7_regL)); 1.3697 + match(iRegL); 1.3698 + 1.3699 + format %{ %} 1.3700 + interface(REG_INTER); 1.3701 +%} 1.3702 + 1.3703 +operand g1RegL() %{ 1.3704 + constraint(ALLOC_IN_RC(g1_regL)); 1.3705 + match(iRegL); 1.3706 + 1.3707 + format %{ %} 1.3708 + interface(REG_INTER); 1.3709 +%} 1.3710 + 1.3711 +// Int Register safe 1.3712 +// This is 64bit safe 1.3713 +operand iRegIsafe() %{ 1.3714 + constraint(ALLOC_IN_RC(long_reg)); 1.3715 + 1.3716 + match(iRegI); 1.3717 + 1.3718 + format %{ %} 1.3719 + interface(REG_INTER); 1.3720 +%} 1.3721 + 1.3722 +// Condition Code Flag Register 1.3723 +operand flagsReg() %{ 1.3724 + constraint(ALLOC_IN_RC(int_flags)); 1.3725 + match(RegFlags); 1.3726 + 1.3727 + format %{ "ccr" %} // both ICC and XCC 1.3728 + interface(REG_INTER); 1.3729 +%} 1.3730 + 1.3731 +// Condition Code Register, unsigned comparisons. 1.3732 +operand flagsRegU() %{ 1.3733 + constraint(ALLOC_IN_RC(int_flags)); 1.3734 + match(RegFlags); 1.3735 + 1.3736 + format %{ "icc_U" %} 1.3737 + interface(REG_INTER); 1.3738 +%} 1.3739 + 1.3740 +// Condition Code Register, pointer comparisons. 1.3741 +operand flagsRegP() %{ 1.3742 + constraint(ALLOC_IN_RC(int_flags)); 1.3743 + match(RegFlags); 1.3744 + 1.3745 +#ifdef _LP64 1.3746 + format %{ "xcc_P" %} 1.3747 +#else 1.3748 + format %{ "icc_P" %} 1.3749 +#endif 1.3750 + interface(REG_INTER); 1.3751 +%} 1.3752 + 1.3753 +// Condition Code Register, long comparisons. 1.3754 +operand flagsRegL() %{ 1.3755 + constraint(ALLOC_IN_RC(int_flags)); 1.3756 + match(RegFlags); 1.3757 + 1.3758 + format %{ "xcc_L" %} 1.3759 + interface(REG_INTER); 1.3760 +%} 1.3761 + 1.3762 +// Condition Code Register, floating comparisons, unordered same as "less". 1.3763 +operand flagsRegF() %{ 1.3764 + constraint(ALLOC_IN_RC(float_flags)); 1.3765 + match(RegFlags); 1.3766 + match(flagsRegF0); 1.3767 + 1.3768 + format %{ %} 1.3769 + interface(REG_INTER); 1.3770 +%} 1.3771 + 1.3772 +operand flagsRegF0() %{ 1.3773 + constraint(ALLOC_IN_RC(float_flag0)); 1.3774 + match(RegFlags); 1.3775 + 1.3776 + format %{ %} 1.3777 + interface(REG_INTER); 1.3778 +%} 1.3779 + 1.3780 + 1.3781 +// Condition Code Flag Register used by long compare 1.3782 +operand flagsReg_long_LTGE() %{ 1.3783 + constraint(ALLOC_IN_RC(int_flags)); 1.3784 + match(RegFlags); 1.3785 + format %{ "icc_LTGE" %} 1.3786 + interface(REG_INTER); 1.3787 +%} 1.3788 +operand flagsReg_long_EQNE() %{ 1.3789 + constraint(ALLOC_IN_RC(int_flags)); 1.3790 + match(RegFlags); 1.3791 + format %{ "icc_EQNE" %} 1.3792 + interface(REG_INTER); 1.3793 +%} 1.3794 +operand flagsReg_long_LEGT() %{ 1.3795 + constraint(ALLOC_IN_RC(int_flags)); 1.3796 + match(RegFlags); 1.3797 + format %{ "icc_LEGT" %} 1.3798 + interface(REG_INTER); 1.3799 +%} 1.3800 + 1.3801 + 1.3802 +operand regD() %{ 1.3803 + constraint(ALLOC_IN_RC(dflt_reg)); 1.3804 + match(RegD); 1.3805 + 1.3806 + format %{ %} 1.3807 + interface(REG_INTER); 1.3808 +%} 1.3809 + 1.3810 +operand regF() %{ 1.3811 + constraint(ALLOC_IN_RC(sflt_reg)); 1.3812 + match(RegF); 1.3813 + 1.3814 + format %{ %} 1.3815 + interface(REG_INTER); 1.3816 +%} 1.3817 + 1.3818 +operand regD_low() %{ 1.3819 + constraint(ALLOC_IN_RC(dflt_low_reg)); 1.3820 + match(RegD); 1.3821 + 1.3822 + format %{ %} 1.3823 + interface(REG_INTER); 1.3824 +%} 1.3825 + 1.3826 +// Special Registers 1.3827 + 1.3828 +// Method Register 1.3829 +operand inline_cache_regP(iRegP reg) %{ 1.3830 + constraint(ALLOC_IN_RC(g5_regP)); // G5=inline_cache_reg but uses 2 bits instead of 1 1.3831 + match(reg); 1.3832 + format %{ %} 1.3833 + interface(REG_INTER); 1.3834 +%} 1.3835 + 1.3836 +operand interpreter_method_oop_regP(iRegP reg) %{ 1.3837 + constraint(ALLOC_IN_RC(g5_regP)); // G5=interpreter_method_oop_reg but uses 2 bits instead of 1 1.3838 + match(reg); 1.3839 + format %{ %} 1.3840 + interface(REG_INTER); 1.3841 +%} 1.3842 + 1.3843 + 1.3844 +//----------Complex Operands--------------------------------------------------- 1.3845 +// Indirect Memory Reference 1.3846 +operand indirect(sp_ptr_RegP reg) %{ 1.3847 + constraint(ALLOC_IN_RC(sp_ptr_reg)); 1.3848 + match(reg); 1.3849 + 1.3850 + op_cost(100); 1.3851 + format %{ "[$reg]" %} 1.3852 + interface(MEMORY_INTER) %{ 1.3853 + base($reg); 1.3854 + index(0x0); 1.3855 + scale(0x0); 1.3856 + disp(0x0); 1.3857 + %} 1.3858 +%} 1.3859 + 1.3860 +// Indirect with Offset 1.3861 +operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{ 1.3862 + constraint(ALLOC_IN_RC(sp_ptr_reg)); 1.3863 + match(AddP reg offset); 1.3864 + 1.3865 + op_cost(100); 1.3866 + format %{ "[$reg + $offset]" %} 1.3867 + interface(MEMORY_INTER) %{ 1.3868 + base($reg); 1.3869 + index(0x0); 1.3870 + scale(0x0); 1.3871 + disp($offset); 1.3872 + %} 1.3873 +%} 1.3874 + 1.3875 +// Note: Intel has a swapped version also, like this: 1.3876 +//operand indOffsetX(iRegI reg, immP offset) %{ 1.3877 +// constraint(ALLOC_IN_RC(int_reg)); 1.3878 +// match(AddP offset reg); 1.3879 +// 1.3880 +// op_cost(100); 1.3881 +// format %{ "[$reg + $offset]" %} 1.3882 +// interface(MEMORY_INTER) %{ 1.3883 +// base($reg); 1.3884 +// index(0x0); 1.3885 +// scale(0x0); 1.3886 +// disp($offset); 1.3887 +// %} 1.3888 +//%} 1.3889 +//// However, it doesn't make sense for SPARC, since 1.3890 +// we have no particularly good way to embed oops in 1.3891 +// single instructions. 1.3892 + 1.3893 +// Indirect with Register Index 1.3894 +operand indIndex(iRegP addr, iRegX index) %{ 1.3895 + constraint(ALLOC_IN_RC(ptr_reg)); 1.3896 + match(AddP addr index); 1.3897 + 1.3898 + op_cost(100); 1.3899 + format %{ "[$addr + $index]" %} 1.3900 + interface(MEMORY_INTER) %{ 1.3901 + base($addr); 1.3902 + index($index); 1.3903 + scale(0x0); 1.3904 + disp(0x0); 1.3905 + %} 1.3906 +%} 1.3907 + 1.3908 +//----------Special Memory Operands-------------------------------------------- 1.3909 +// Stack Slot Operand - This operand is used for loading and storing temporary 1.3910 +// values on the stack where a match requires a value to 1.3911 +// flow through memory. 1.3912 +operand stackSlotI(sRegI reg) %{ 1.3913 + constraint(ALLOC_IN_RC(stack_slots)); 1.3914 + op_cost(100); 1.3915 + //match(RegI); 1.3916 + format %{ "[$reg]" %} 1.3917 + interface(MEMORY_INTER) %{ 1.3918 + base(0xE); // R_SP 1.3919 + index(0x0); 1.3920 + scale(0x0); 1.3921 + disp($reg); // Stack Offset 1.3922 + %} 1.3923 +%} 1.3924 + 1.3925 +operand stackSlotP(sRegP reg) %{ 1.3926 + constraint(ALLOC_IN_RC(stack_slots)); 1.3927 + op_cost(100); 1.3928 + //match(RegP); 1.3929 + format %{ "[$reg]" %} 1.3930 + interface(MEMORY_INTER) %{ 1.3931 + base(0xE); // R_SP 1.3932 + index(0x0); 1.3933 + scale(0x0); 1.3934 + disp($reg); // Stack Offset 1.3935 + %} 1.3936 +%} 1.3937 + 1.3938 +operand stackSlotF(sRegF reg) %{ 1.3939 + constraint(ALLOC_IN_RC(stack_slots)); 1.3940 + op_cost(100); 1.3941 + //match(RegF); 1.3942 + format %{ "[$reg]" %} 1.3943 + interface(MEMORY_INTER) %{ 1.3944 + base(0xE); // R_SP 1.3945 + index(0x0); 1.3946 + scale(0x0); 1.3947 + disp($reg); // Stack Offset 1.3948 + %} 1.3949 +%} 1.3950 +operand stackSlotD(sRegD reg) %{ 1.3951 + constraint(ALLOC_IN_RC(stack_slots)); 1.3952 + op_cost(100); 1.3953 + //match(RegD); 1.3954 + format %{ "[$reg]" %} 1.3955 + interface(MEMORY_INTER) %{ 1.3956 + base(0xE); // R_SP 1.3957 + index(0x0); 1.3958 + scale(0x0); 1.3959 + disp($reg); // Stack Offset 1.3960 + %} 1.3961 +%} 1.3962 +operand stackSlotL(sRegL reg) %{ 1.3963 + constraint(ALLOC_IN_RC(stack_slots)); 1.3964 + op_cost(100); 1.3965 + //match(RegL); 1.3966 + format %{ "[$reg]" %} 1.3967 + interface(MEMORY_INTER) %{ 1.3968 + base(0xE); // R_SP 1.3969 + index(0x0); 1.3970 + scale(0x0); 1.3971 + disp($reg); // Stack Offset 1.3972 + %} 1.3973 +%} 1.3974 + 1.3975 +// Operands for expressing Control Flow 1.3976 +// NOTE: Label is a predefined operand which should not be redefined in 1.3977 +// the AD file. It is generically handled within the ADLC. 1.3978 + 1.3979 +//----------Conditional Branch Operands---------------------------------------- 1.3980 +// Comparison Op - This is the operation of the comparison, and is limited to 1.3981 +// the following set of codes: 1.3982 +// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 1.3983 +// 1.3984 +// Other attributes of the comparison, such as unsignedness, are specified 1.3985 +// by the comparison instruction that sets a condition code flags register. 1.3986 +// That result is represented by a flags operand whose subtype is appropriate 1.3987 +// to the unsignedness (etc.) of the comparison. 1.3988 +// 1.3989 +// Later, the instruction which matches both the Comparison Op (a Bool) and 1.3990 +// the flags (produced by the Cmp) specifies the coding of the comparison op 1.3991 +// by matching a specific subtype of Bool operand below, such as cmpOpU. 1.3992 + 1.3993 +operand cmpOp() %{ 1.3994 + match(Bool); 1.3995 + 1.3996 + format %{ "" %} 1.3997 + interface(COND_INTER) %{ 1.3998 + equal(0x1); 1.3999 + not_equal(0x9); 1.4000 + less(0x3); 1.4001 + greater_equal(0xB); 1.4002 + less_equal(0x2); 1.4003 + greater(0xA); 1.4004 + %} 1.4005 +%} 1.4006 + 1.4007 +// Comparison Op, unsigned 1.4008 +operand cmpOpU() %{ 1.4009 + match(Bool); 1.4010 + 1.4011 + format %{ "u" %} 1.4012 + interface(COND_INTER) %{ 1.4013 + equal(0x1); 1.4014 + not_equal(0x9); 1.4015 + less(0x5); 1.4016 + greater_equal(0xD); 1.4017 + less_equal(0x4); 1.4018 + greater(0xC); 1.4019 + %} 1.4020 +%} 1.4021 + 1.4022 +// Comparison Op, pointer (same as unsigned) 1.4023 +operand cmpOpP() %{ 1.4024 + match(Bool); 1.4025 + 1.4026 + format %{ "p" %} 1.4027 + interface(COND_INTER) %{ 1.4028 + equal(0x1); 1.4029 + not_equal(0x9); 1.4030 + less(0x5); 1.4031 + greater_equal(0xD); 1.4032 + less_equal(0x4); 1.4033 + greater(0xC); 1.4034 + %} 1.4035 +%} 1.4036 + 1.4037 +// Comparison Op, branch-register encoding 1.4038 +operand cmpOp_reg() %{ 1.4039 + match(Bool); 1.4040 + 1.4041 + format %{ "" %} 1.4042 + interface(COND_INTER) %{ 1.4043 + equal (0x1); 1.4044 + not_equal (0x5); 1.4045 + less (0x3); 1.4046 + greater_equal(0x7); 1.4047 + less_equal (0x2); 1.4048 + greater (0x6); 1.4049 + %} 1.4050 +%} 1.4051 + 1.4052 +// Comparison Code, floating, unordered same as less 1.4053 +operand cmpOpF() %{ 1.4054 + match(Bool); 1.4055 + 1.4056 + format %{ "fl" %} 1.4057 + interface(COND_INTER) %{ 1.4058 + equal(0x9); 1.4059 + not_equal(0x1); 1.4060 + less(0x3); 1.4061 + greater_equal(0xB); 1.4062 + less_equal(0xE); 1.4063 + greater(0x6); 1.4064 + %} 1.4065 +%} 1.4066 + 1.4067 +// Used by long compare 1.4068 +operand cmpOp_commute() %{ 1.4069 + match(Bool); 1.4070 + 1.4071 + format %{ "" %} 1.4072 + interface(COND_INTER) %{ 1.4073 + equal(0x1); 1.4074 + not_equal(0x9); 1.4075 + less(0xA); 1.4076 + greater_equal(0x2); 1.4077 + less_equal(0xB); 1.4078 + greater(0x3); 1.4079 + %} 1.4080 +%} 1.4081 + 1.4082 +//----------OPERAND CLASSES---------------------------------------------------- 1.4083 +// Operand Classes are groups of operands that are used to simplify 1.4084 +// instruction definitions by not requiring the AD writer to specify seperate 1.4085 +// instructions for every form of operand when the instruction accepts 1.4086 +// multiple operand types with the same basic encoding and format. The classic 1.4087 +// case of this is memory operands. 1.4088 +// Indirect is not included since its use is limited to Compare & Swap 1.4089 +opclass memory( indirect, indOffset13, indIndex ); 1.4090 + 1.4091 +//----------PIPELINE----------------------------------------------------------- 1.4092 +pipeline %{ 1.4093 + 1.4094 +//----------ATTRIBUTES--------------------------------------------------------- 1.4095 +attributes %{ 1.4096 + fixed_size_instructions; // Fixed size instructions 1.4097 + branch_has_delay_slot; // Branch has delay slot following 1.4098 + max_instructions_per_bundle = 4; // Up to 4 instructions per bundle 1.4099 + instruction_unit_size = 4; // An instruction is 4 bytes long 1.4100 + instruction_fetch_unit_size = 16; // The processor fetches one line 1.4101 + instruction_fetch_units = 1; // of 16 bytes 1.4102 + 1.4103 + // List of nop instructions 1.4104 + nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR ); 1.4105 +%} 1.4106 + 1.4107 +//----------RESOURCES---------------------------------------------------------- 1.4108 +// Resources are the functional units available to the machine 1.4109 +resources(A0, A1, MS, BR, FA, FM, IDIV, FDIV, IALU = A0 | A1); 1.4110 + 1.4111 +//----------PIPELINE DESCRIPTION----------------------------------------------- 1.4112 +// Pipeline Description specifies the stages in the machine's pipeline 1.4113 + 1.4114 +pipe_desc(A, P, F, B, I, J, S, R, E, C, M, W, X, T, D); 1.4115 + 1.4116 +//----------PIPELINE CLASSES--------------------------------------------------- 1.4117 +// Pipeline Classes describe the stages in which input and output are 1.4118 +// referenced by the hardware pipeline. 1.4119 + 1.4120 +// Integer ALU reg-reg operation 1.4121 +pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.4122 + single_instruction; 1.4123 + dst : E(write); 1.4124 + src1 : R(read); 1.4125 + src2 : R(read); 1.4126 + IALU : R; 1.4127 +%} 1.4128 + 1.4129 +// Integer ALU reg-reg long operation 1.4130 +pipe_class ialu_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{ 1.4131 + instruction_count(2); 1.4132 + dst : E(write); 1.4133 + src1 : R(read); 1.4134 + src2 : R(read); 1.4135 + IALU : R; 1.4136 + IALU : R; 1.4137 +%} 1.4138 + 1.4139 +// Integer ALU reg-reg long dependent operation 1.4140 +pipe_class ialu_reg_reg_2_dep(iRegL dst, iRegL src1, iRegL src2, flagsReg cr) %{ 1.4141 + instruction_count(1); multiple_bundles; 1.4142 + dst : E(write); 1.4143 + src1 : R(read); 1.4144 + src2 : R(read); 1.4145 + cr : E(write); 1.4146 + IALU : R(2); 1.4147 +%} 1.4148 + 1.4149 +// Integer ALU reg-imm operaion 1.4150 +pipe_class ialu_reg_imm(iRegI dst, iRegI src1, immI13 src2) %{ 1.4151 + single_instruction; 1.4152 + dst : E(write); 1.4153 + src1 : R(read); 1.4154 + IALU : R; 1.4155 +%} 1.4156 + 1.4157 +// Integer ALU reg-reg operation with condition code 1.4158 +pipe_class ialu_cc_reg_reg(iRegI dst, iRegI src1, iRegI src2, flagsReg cr) %{ 1.4159 + single_instruction; 1.4160 + dst : E(write); 1.4161 + cr : E(write); 1.4162 + src1 : R(read); 1.4163 + src2 : R(read); 1.4164 + IALU : R; 1.4165 +%} 1.4166 + 1.4167 +// Integer ALU reg-imm operation with condition code 1.4168 +pipe_class ialu_cc_reg_imm(iRegI dst, iRegI src1, immI13 src2, flagsReg cr) %{ 1.4169 + single_instruction; 1.4170 + dst : E(write); 1.4171 + cr : E(write); 1.4172 + src1 : R(read); 1.4173 + IALU : R; 1.4174 +%} 1.4175 + 1.4176 +// Integer ALU zero-reg operation 1.4177 +pipe_class ialu_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{ 1.4178 + single_instruction; 1.4179 + dst : E(write); 1.4180 + src2 : R(read); 1.4181 + IALU : R; 1.4182 +%} 1.4183 + 1.4184 +// Integer ALU zero-reg operation with condition code only 1.4185 +pipe_class ialu_cconly_zero_reg(flagsReg cr, iRegI src) %{ 1.4186 + single_instruction; 1.4187 + cr : E(write); 1.4188 + src : R(read); 1.4189 + IALU : R; 1.4190 +%} 1.4191 + 1.4192 +// Integer ALU reg-reg operation with condition code only 1.4193 +pipe_class ialu_cconly_reg_reg(flagsReg cr, iRegI src1, iRegI src2) %{ 1.4194 + single_instruction; 1.4195 + cr : E(write); 1.4196 + src1 : R(read); 1.4197 + src2 : R(read); 1.4198 + IALU : R; 1.4199 +%} 1.4200 + 1.4201 +// Integer ALU reg-imm operation with condition code only 1.4202 +pipe_class ialu_cconly_reg_imm(flagsReg cr, iRegI src1, immI13 src2) %{ 1.4203 + single_instruction; 1.4204 + cr : E(write); 1.4205 + src1 : R(read); 1.4206 + IALU : R; 1.4207 +%} 1.4208 + 1.4209 +// Integer ALU reg-reg-zero operation with condition code only 1.4210 +pipe_class ialu_cconly_reg_reg_zero(flagsReg cr, iRegI src1, iRegI src2, immI0 zero) %{ 1.4211 + single_instruction; 1.4212 + cr : E(write); 1.4213 + src1 : R(read); 1.4214 + src2 : R(read); 1.4215 + IALU : R; 1.4216 +%} 1.4217 + 1.4218 +// Integer ALU reg-imm-zero operation with condition code only 1.4219 +pipe_class ialu_cconly_reg_imm_zero(flagsReg cr, iRegI src1, immI13 src2, immI0 zero) %{ 1.4220 + single_instruction; 1.4221 + cr : E(write); 1.4222 + src1 : R(read); 1.4223 + IALU : R; 1.4224 +%} 1.4225 + 1.4226 +// Integer ALU reg-reg operation with condition code, src1 modified 1.4227 +pipe_class ialu_cc_rwreg_reg(flagsReg cr, iRegI src1, iRegI src2) %{ 1.4228 + single_instruction; 1.4229 + cr : E(write); 1.4230 + src1 : E(write); 1.4231 + src1 : R(read); 1.4232 + src2 : R(read); 1.4233 + IALU : R; 1.4234 +%} 1.4235 + 1.4236 +// Integer ALU reg-imm operation with condition code, src1 modified 1.4237 +pipe_class ialu_cc_rwreg_imm(flagsReg cr, iRegI src1, immI13 src2) %{ 1.4238 + single_instruction; 1.4239 + cr : E(write); 1.4240 + src1 : E(write); 1.4241 + src1 : R(read); 1.4242 + IALU : R; 1.4243 +%} 1.4244 + 1.4245 +pipe_class cmpL_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg cr ) %{ 1.4246 + multiple_bundles; 1.4247 + dst : E(write)+4; 1.4248 + cr : E(write); 1.4249 + src1 : R(read); 1.4250 + src2 : R(read); 1.4251 + IALU : R(3); 1.4252 + BR : R(2); 1.4253 +%} 1.4254 + 1.4255 +// Integer ALU operation 1.4256 +pipe_class ialu_none(iRegI dst) %{ 1.4257 + single_instruction; 1.4258 + dst : E(write); 1.4259 + IALU : R; 1.4260 +%} 1.4261 + 1.4262 +// Integer ALU reg operation 1.4263 +pipe_class ialu_reg(iRegI dst, iRegI src) %{ 1.4264 + single_instruction; may_have_no_code; 1.4265 + dst : E(write); 1.4266 + src : R(read); 1.4267 + IALU : R; 1.4268 +%} 1.4269 + 1.4270 +// Integer ALU reg conditional operation 1.4271 +// This instruction has a 1 cycle stall, and cannot execute 1.4272 +// in the same cycle as the instruction setting the condition 1.4273 +// code. We kludge this by pretending to read the condition code 1.4274 +// 1 cycle earlier, and by marking the functional units as busy 1.4275 +// for 2 cycles with the result available 1 cycle later than 1.4276 +// is really the case. 1.4277 +pipe_class ialu_reg_flags( iRegI op2_out, iRegI op2_in, iRegI op1, flagsReg cr ) %{ 1.4278 + single_instruction; 1.4279 + op2_out : C(write); 1.4280 + op1 : R(read); 1.4281 + cr : R(read); // This is really E, with a 1 cycle stall 1.4282 + BR : R(2); 1.4283 + MS : R(2); 1.4284 +%} 1.4285 + 1.4286 +#ifdef _LP64 1.4287 +pipe_class ialu_clr_and_mover( iRegI dst, iRegP src ) %{ 1.4288 + instruction_count(1); multiple_bundles; 1.4289 + dst : C(write)+1; 1.4290 + src : R(read)+1; 1.4291 + IALU : R(1); 1.4292 + BR : E(2); 1.4293 + MS : E(2); 1.4294 +%} 1.4295 +#endif 1.4296 + 1.4297 +// Integer ALU reg operation 1.4298 +pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{ 1.4299 + single_instruction; may_have_no_code; 1.4300 + dst : E(write); 1.4301 + src : R(read); 1.4302 + IALU : R; 1.4303 +%} 1.4304 +pipe_class ialu_move_reg_I_to_L(iRegL dst, iRegI src) %{ 1.4305 + single_instruction; may_have_no_code; 1.4306 + dst : E(write); 1.4307 + src : R(read); 1.4308 + IALU : R; 1.4309 +%} 1.4310 + 1.4311 +// Two integer ALU reg operations 1.4312 +pipe_class ialu_reg_2(iRegL dst, iRegL src) %{ 1.4313 + instruction_count(2); 1.4314 + dst : E(write); 1.4315 + src : R(read); 1.4316 + A0 : R; 1.4317 + A1 : R; 1.4318 +%} 1.4319 + 1.4320 +// Two integer ALU reg operations 1.4321 +pipe_class ialu_move_reg_L_to_L(iRegL dst, iRegL src) %{ 1.4322 + instruction_count(2); may_have_no_code; 1.4323 + dst : E(write); 1.4324 + src : R(read); 1.4325 + A0 : R; 1.4326 + A1 : R; 1.4327 +%} 1.4328 + 1.4329 +// Integer ALU imm operation 1.4330 +pipe_class ialu_imm(iRegI dst, immI13 src) %{ 1.4331 + single_instruction; 1.4332 + dst : E(write); 1.4333 + IALU : R; 1.4334 +%} 1.4335 + 1.4336 +// Integer ALU reg-reg with carry operation 1.4337 +pipe_class ialu_reg_reg_cy(iRegI dst, iRegI src1, iRegI src2, iRegI cy) %{ 1.4338 + single_instruction; 1.4339 + dst : E(write); 1.4340 + src1 : R(read); 1.4341 + src2 : R(read); 1.4342 + IALU : R; 1.4343 +%} 1.4344 + 1.4345 +// Integer ALU cc operation 1.4346 +pipe_class ialu_cc(iRegI dst, flagsReg cc) %{ 1.4347 + single_instruction; 1.4348 + dst : E(write); 1.4349 + cc : R(read); 1.4350 + IALU : R; 1.4351 +%} 1.4352 + 1.4353 +// Integer ALU cc / second IALU operation 1.4354 +pipe_class ialu_reg_ialu( iRegI dst, iRegI src ) %{ 1.4355 + instruction_count(1); multiple_bundles; 1.4356 + dst : E(write)+1; 1.4357 + src : R(read); 1.4358 + IALU : R; 1.4359 +%} 1.4360 + 1.4361 +// Integer ALU cc / second IALU operation 1.4362 +pipe_class ialu_reg_reg_ialu( iRegI dst, iRegI p, iRegI q ) %{ 1.4363 + instruction_count(1); multiple_bundles; 1.4364 + dst : E(write)+1; 1.4365 + p : R(read); 1.4366 + q : R(read); 1.4367 + IALU : R; 1.4368 +%} 1.4369 + 1.4370 +// Integer ALU hi-lo-reg operation 1.4371 +pipe_class ialu_hi_lo_reg(iRegI dst, immI src) %{ 1.4372 + instruction_count(1); multiple_bundles; 1.4373 + dst : E(write)+1; 1.4374 + IALU : R(2); 1.4375 +%} 1.4376 + 1.4377 +// Float ALU hi-lo-reg operation (with temp) 1.4378 +pipe_class ialu_hi_lo_reg_temp(regF dst, immF src, g3RegP tmp) %{ 1.4379 + instruction_count(1); multiple_bundles; 1.4380 + dst : E(write)+1; 1.4381 + IALU : R(2); 1.4382 +%} 1.4383 + 1.4384 +// Long Constant 1.4385 +pipe_class loadConL( iRegL dst, immL src ) %{ 1.4386 + instruction_count(2); multiple_bundles; 1.4387 + dst : E(write)+1; 1.4388 + IALU : R(2); 1.4389 + IALU : R(2); 1.4390 +%} 1.4391 + 1.4392 +// Pointer Constant 1.4393 +pipe_class loadConP( iRegP dst, immP src ) %{ 1.4394 + instruction_count(0); multiple_bundles; 1.4395 + fixed_latency(6); 1.4396 +%} 1.4397 + 1.4398 +// Polling Address 1.4399 +pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{ 1.4400 +#ifdef _LP64 1.4401 + instruction_count(0); multiple_bundles; 1.4402 + fixed_latency(6); 1.4403 +#else 1.4404 + dst : E(write); 1.4405 + IALU : R; 1.4406 +#endif 1.4407 +%} 1.4408 + 1.4409 +// Long Constant small 1.4410 +pipe_class loadConLlo( iRegL dst, immL src ) %{ 1.4411 + instruction_count(2); 1.4412 + dst : E(write); 1.4413 + IALU : R; 1.4414 + IALU : R; 1.4415 +%} 1.4416 + 1.4417 +// [PHH] This is wrong for 64-bit. See LdImmF/D. 1.4418 +pipe_class loadConFD(regF dst, immF src, g3RegP tmp) %{ 1.4419 + instruction_count(1); multiple_bundles; 1.4420 + src : R(read); 1.4421 + dst : M(write)+1; 1.4422 + IALU : R; 1.4423 + MS : E; 1.4424 +%} 1.4425 + 1.4426 +// Integer ALU nop operation 1.4427 +pipe_class ialu_nop() %{ 1.4428 + single_instruction; 1.4429 + IALU : R; 1.4430 +%} 1.4431 + 1.4432 +// Integer ALU nop operation 1.4433 +pipe_class ialu_nop_A0() %{ 1.4434 + single_instruction; 1.4435 + A0 : R; 1.4436 +%} 1.4437 + 1.4438 +// Integer ALU nop operation 1.4439 +pipe_class ialu_nop_A1() %{ 1.4440 + single_instruction; 1.4441 + A1 : R; 1.4442 +%} 1.4443 + 1.4444 +// Integer Multiply reg-reg operation 1.4445 +pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.4446 + single_instruction; 1.4447 + dst : E(write); 1.4448 + src1 : R(read); 1.4449 + src2 : R(read); 1.4450 + MS : R(5); 1.4451 +%} 1.4452 + 1.4453 +// Integer Multiply reg-imm operation 1.4454 +pipe_class imul_reg_imm(iRegI dst, iRegI src1, immI13 src2) %{ 1.4455 + single_instruction; 1.4456 + dst : E(write); 1.4457 + src1 : R(read); 1.4458 + MS : R(5); 1.4459 +%} 1.4460 + 1.4461 +pipe_class mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.4462 + single_instruction; 1.4463 + dst : E(write)+4; 1.4464 + src1 : R(read); 1.4465 + src2 : R(read); 1.4466 + MS : R(6); 1.4467 +%} 1.4468 + 1.4469 +pipe_class mulL_reg_imm(iRegL dst, iRegL src1, immL13 src2) %{ 1.4470 + single_instruction; 1.4471 + dst : E(write)+4; 1.4472 + src1 : R(read); 1.4473 + MS : R(6); 1.4474 +%} 1.4475 + 1.4476 +// Integer Divide reg-reg 1.4477 +pipe_class sdiv_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI temp, flagsReg cr) %{ 1.4478 + instruction_count(1); multiple_bundles; 1.4479 + dst : E(write); 1.4480 + temp : E(write); 1.4481 + src1 : R(read); 1.4482 + src2 : R(read); 1.4483 + temp : R(read); 1.4484 + MS : R(38); 1.4485 +%} 1.4486 + 1.4487 +// Integer Divide reg-imm 1.4488 +pipe_class sdiv_reg_imm(iRegI dst, iRegI src1, immI13 src2, iRegI temp, flagsReg cr) %{ 1.4489 + instruction_count(1); multiple_bundles; 1.4490 + dst : E(write); 1.4491 + temp : E(write); 1.4492 + src1 : R(read); 1.4493 + temp : R(read); 1.4494 + MS : R(38); 1.4495 +%} 1.4496 + 1.4497 +// Long Divide 1.4498 +pipe_class divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.4499 + dst : E(write)+71; 1.4500 + src1 : R(read); 1.4501 + src2 : R(read)+1; 1.4502 + MS : R(70); 1.4503 +%} 1.4504 + 1.4505 +pipe_class divL_reg_imm(iRegL dst, iRegL src1, immL13 src2) %{ 1.4506 + dst : E(write)+71; 1.4507 + src1 : R(read); 1.4508 + MS : R(70); 1.4509 +%} 1.4510 + 1.4511 +// Floating Point Add Float 1.4512 +pipe_class faddF_reg_reg(regF dst, regF src1, regF src2) %{ 1.4513 + single_instruction; 1.4514 + dst : X(write); 1.4515 + src1 : E(read); 1.4516 + src2 : E(read); 1.4517 + FA : R; 1.4518 +%} 1.4519 + 1.4520 +// Floating Point Add Double 1.4521 +pipe_class faddD_reg_reg(regD dst, regD src1, regD src2) %{ 1.4522 + single_instruction; 1.4523 + dst : X(write); 1.4524 + src1 : E(read); 1.4525 + src2 : E(read); 1.4526 + FA : R; 1.4527 +%} 1.4528 + 1.4529 +// Floating Point Conditional Move based on integer flags 1.4530 +pipe_class int_conditional_float_move (cmpOp cmp, flagsReg cr, regF dst, regF src) %{ 1.4531 + single_instruction; 1.4532 + dst : X(write); 1.4533 + src : E(read); 1.4534 + cr : R(read); 1.4535 + FA : R(2); 1.4536 + BR : R(2); 1.4537 +%} 1.4538 + 1.4539 +// Floating Point Conditional Move based on integer flags 1.4540 +pipe_class int_conditional_double_move (cmpOp cmp, flagsReg cr, regD dst, regD src) %{ 1.4541 + single_instruction; 1.4542 + dst : X(write); 1.4543 + src : E(read); 1.4544 + cr : R(read); 1.4545 + FA : R(2); 1.4546 + BR : R(2); 1.4547 +%} 1.4548 + 1.4549 +// Floating Point Multiply Float 1.4550 +pipe_class fmulF_reg_reg(regF dst, regF src1, regF src2) %{ 1.4551 + single_instruction; 1.4552 + dst : X(write); 1.4553 + src1 : E(read); 1.4554 + src2 : E(read); 1.4555 + FM : R; 1.4556 +%} 1.4557 + 1.4558 +// Floating Point Multiply Double 1.4559 +pipe_class fmulD_reg_reg(regD dst, regD src1, regD src2) %{ 1.4560 + single_instruction; 1.4561 + dst : X(write); 1.4562 + src1 : E(read); 1.4563 + src2 : E(read); 1.4564 + FM : R; 1.4565 +%} 1.4566 + 1.4567 +// Floating Point Divide Float 1.4568 +pipe_class fdivF_reg_reg(regF dst, regF src1, regF src2) %{ 1.4569 + single_instruction; 1.4570 + dst : X(write); 1.4571 + src1 : E(read); 1.4572 + src2 : E(read); 1.4573 + FM : R; 1.4574 + FDIV : C(14); 1.4575 +%} 1.4576 + 1.4577 +// Floating Point Divide Double 1.4578 +pipe_class fdivD_reg_reg(regD dst, regD src1, regD src2) %{ 1.4579 + single_instruction; 1.4580 + dst : X(write); 1.4581 + src1 : E(read); 1.4582 + src2 : E(read); 1.4583 + FM : R; 1.4584 + FDIV : C(17); 1.4585 +%} 1.4586 + 1.4587 +// Floating Point Move/Negate/Abs Float 1.4588 +pipe_class faddF_reg(regF dst, regF src) %{ 1.4589 + single_instruction; 1.4590 + dst : W(write); 1.4591 + src : E(read); 1.4592 + FA : R(1); 1.4593 +%} 1.4594 + 1.4595 +// Floating Point Move/Negate/Abs Double 1.4596 +pipe_class faddD_reg(regD dst, regD src) %{ 1.4597 + single_instruction; 1.4598 + dst : W(write); 1.4599 + src : E(read); 1.4600 + FA : R; 1.4601 +%} 1.4602 + 1.4603 +// Floating Point Convert F->D 1.4604 +pipe_class fcvtF2D(regD dst, regF src) %{ 1.4605 + single_instruction; 1.4606 + dst : X(write); 1.4607 + src : E(read); 1.4608 + FA : R; 1.4609 +%} 1.4610 + 1.4611 +// Floating Point Convert I->D 1.4612 +pipe_class fcvtI2D(regD dst, regF src) %{ 1.4613 + single_instruction; 1.4614 + dst : X(write); 1.4615 + src : E(read); 1.4616 + FA : R; 1.4617 +%} 1.4618 + 1.4619 +// Floating Point Convert LHi->D 1.4620 +pipe_class fcvtLHi2D(regD dst, regD src) %{ 1.4621 + single_instruction; 1.4622 + dst : X(write); 1.4623 + src : E(read); 1.4624 + FA : R; 1.4625 +%} 1.4626 + 1.4627 +// Floating Point Convert L->D 1.4628 +pipe_class fcvtL2D(regD dst, regF src) %{ 1.4629 + single_instruction; 1.4630 + dst : X(write); 1.4631 + src : E(read); 1.4632 + FA : R; 1.4633 +%} 1.4634 + 1.4635 +// Floating Point Convert L->F 1.4636 +pipe_class fcvtL2F(regD dst, regF src) %{ 1.4637 + single_instruction; 1.4638 + dst : X(write); 1.4639 + src : E(read); 1.4640 + FA : R; 1.4641 +%} 1.4642 + 1.4643 +// Floating Point Convert D->F 1.4644 +pipe_class fcvtD2F(regD dst, regF src) %{ 1.4645 + single_instruction; 1.4646 + dst : X(write); 1.4647 + src : E(read); 1.4648 + FA : R; 1.4649 +%} 1.4650 + 1.4651 +// Floating Point Convert I->L 1.4652 +pipe_class fcvtI2L(regD dst, regF src) %{ 1.4653 + single_instruction; 1.4654 + dst : X(write); 1.4655 + src : E(read); 1.4656 + FA : R; 1.4657 +%} 1.4658 + 1.4659 +// Floating Point Convert D->F 1.4660 +pipe_class fcvtD2I(regF dst, regD src, flagsReg cr) %{ 1.4661 + instruction_count(1); multiple_bundles; 1.4662 + dst : X(write)+6; 1.4663 + src : E(read); 1.4664 + FA : R; 1.4665 +%} 1.4666 + 1.4667 +// Floating Point Convert D->L 1.4668 +pipe_class fcvtD2L(regD dst, regD src, flagsReg cr) %{ 1.4669 + instruction_count(1); multiple_bundles; 1.4670 + dst : X(write)+6; 1.4671 + src : E(read); 1.4672 + FA : R; 1.4673 +%} 1.4674 + 1.4675 +// Floating Point Convert F->I 1.4676 +pipe_class fcvtF2I(regF dst, regF src, flagsReg cr) %{ 1.4677 + instruction_count(1); multiple_bundles; 1.4678 + dst : X(write)+6; 1.4679 + src : E(read); 1.4680 + FA : R; 1.4681 +%} 1.4682 + 1.4683 +// Floating Point Convert F->L 1.4684 +pipe_class fcvtF2L(regD dst, regF src, flagsReg cr) %{ 1.4685 + instruction_count(1); multiple_bundles; 1.4686 + dst : X(write)+6; 1.4687 + src : E(read); 1.4688 + FA : R; 1.4689 +%} 1.4690 + 1.4691 +// Floating Point Convert I->F 1.4692 +pipe_class fcvtI2F(regF dst, regF src) %{ 1.4693 + single_instruction; 1.4694 + dst : X(write); 1.4695 + src : E(read); 1.4696 + FA : R; 1.4697 +%} 1.4698 + 1.4699 +// Floating Point Compare 1.4700 +pipe_class faddF_fcc_reg_reg_zero(flagsRegF cr, regF src1, regF src2, immI0 zero) %{ 1.4701 + single_instruction; 1.4702 + cr : X(write); 1.4703 + src1 : E(read); 1.4704 + src2 : E(read); 1.4705 + FA : R; 1.4706 +%} 1.4707 + 1.4708 +// Floating Point Compare 1.4709 +pipe_class faddD_fcc_reg_reg_zero(flagsRegF cr, regD src1, regD src2, immI0 zero) %{ 1.4710 + single_instruction; 1.4711 + cr : X(write); 1.4712 + src1 : E(read); 1.4713 + src2 : E(read); 1.4714 + FA : R; 1.4715 +%} 1.4716 + 1.4717 +// Floating Add Nop 1.4718 +pipe_class fadd_nop() %{ 1.4719 + single_instruction; 1.4720 + FA : R; 1.4721 +%} 1.4722 + 1.4723 +// Integer Store to Memory 1.4724 +pipe_class istore_mem_reg(memory mem, iRegI src) %{ 1.4725 + single_instruction; 1.4726 + mem : R(read); 1.4727 + src : C(read); 1.4728 + MS : R; 1.4729 +%} 1.4730 + 1.4731 +// Integer Store to Memory 1.4732 +pipe_class istore_mem_spORreg(memory mem, sp_ptr_RegP src) %{ 1.4733 + single_instruction; 1.4734 + mem : R(read); 1.4735 + src : C(read); 1.4736 + MS : R; 1.4737 +%} 1.4738 + 1.4739 +// Integer Store Zero to Memory 1.4740 +pipe_class istore_mem_zero(memory mem, immI0 src) %{ 1.4741 + single_instruction; 1.4742 + mem : R(read); 1.4743 + MS : R; 1.4744 +%} 1.4745 + 1.4746 +// Special Stack Slot Store 1.4747 +pipe_class istore_stk_reg(stackSlotI stkSlot, iRegI src) %{ 1.4748 + single_instruction; 1.4749 + stkSlot : R(read); 1.4750 + src : C(read); 1.4751 + MS : R; 1.4752 +%} 1.4753 + 1.4754 +// Special Stack Slot Store 1.4755 +pipe_class lstoreI_stk_reg(stackSlotL stkSlot, iRegI src) %{ 1.4756 + instruction_count(2); multiple_bundles; 1.4757 + stkSlot : R(read); 1.4758 + src : C(read); 1.4759 + MS : R(2); 1.4760 +%} 1.4761 + 1.4762 +// Float Store 1.4763 +pipe_class fstoreF_mem_reg(memory mem, RegF src) %{ 1.4764 + single_instruction; 1.4765 + mem : R(read); 1.4766 + src : C(read); 1.4767 + MS : R; 1.4768 +%} 1.4769 + 1.4770 +// Float Store 1.4771 +pipe_class fstoreF_mem_zero(memory mem, immF0 src) %{ 1.4772 + single_instruction; 1.4773 + mem : R(read); 1.4774 + MS : R; 1.4775 +%} 1.4776 + 1.4777 +// Double Store 1.4778 +pipe_class fstoreD_mem_reg(memory mem, RegD src) %{ 1.4779 + instruction_count(1); 1.4780 + mem : R(read); 1.4781 + src : C(read); 1.4782 + MS : R; 1.4783 +%} 1.4784 + 1.4785 +// Double Store 1.4786 +pipe_class fstoreD_mem_zero(memory mem, immD0 src) %{ 1.4787 + single_instruction; 1.4788 + mem : R(read); 1.4789 + MS : R; 1.4790 +%} 1.4791 + 1.4792 +// Special Stack Slot Float Store 1.4793 +pipe_class fstoreF_stk_reg(stackSlotI stkSlot, RegF src) %{ 1.4794 + single_instruction; 1.4795 + stkSlot : R(read); 1.4796 + src : C(read); 1.4797 + MS : R; 1.4798 +%} 1.4799 + 1.4800 +// Special Stack Slot Double Store 1.4801 +pipe_class fstoreD_stk_reg(stackSlotI stkSlot, RegD src) %{ 1.4802 + single_instruction; 1.4803 + stkSlot : R(read); 1.4804 + src : C(read); 1.4805 + MS : R; 1.4806 +%} 1.4807 + 1.4808 +// Integer Load (when sign bit propagation not needed) 1.4809 +pipe_class iload_mem(iRegI dst, memory mem) %{ 1.4810 + single_instruction; 1.4811 + mem : R(read); 1.4812 + dst : C(write); 1.4813 + MS : R; 1.4814 +%} 1.4815 + 1.4816 +// Integer Load from stack operand 1.4817 +pipe_class iload_stkD(iRegI dst, stackSlotD mem ) %{ 1.4818 + single_instruction; 1.4819 + mem : R(read); 1.4820 + dst : C(write); 1.4821 + MS : R; 1.4822 +%} 1.4823 + 1.4824 +// Integer Load (when sign bit propagation or masking is needed) 1.4825 +pipe_class iload_mask_mem(iRegI dst, memory mem) %{ 1.4826 + single_instruction; 1.4827 + mem : R(read); 1.4828 + dst : M(write); 1.4829 + MS : R; 1.4830 +%} 1.4831 + 1.4832 +// Float Load 1.4833 +pipe_class floadF_mem(regF dst, memory mem) %{ 1.4834 + single_instruction; 1.4835 + mem : R(read); 1.4836 + dst : M(write); 1.4837 + MS : R; 1.4838 +%} 1.4839 + 1.4840 +// Float Load 1.4841 +pipe_class floadD_mem(regD dst, memory mem) %{ 1.4842 + instruction_count(1); multiple_bundles; // Again, unaligned argument is only multiple case 1.4843 + mem : R(read); 1.4844 + dst : M(write); 1.4845 + MS : R; 1.4846 +%} 1.4847 + 1.4848 +// Float Load 1.4849 +pipe_class floadF_stk(regF dst, stackSlotI stkSlot) %{ 1.4850 + single_instruction; 1.4851 + stkSlot : R(read); 1.4852 + dst : M(write); 1.4853 + MS : R; 1.4854 +%} 1.4855 + 1.4856 +// Float Load 1.4857 +pipe_class floadD_stk(regD dst, stackSlotI stkSlot) %{ 1.4858 + single_instruction; 1.4859 + stkSlot : R(read); 1.4860 + dst : M(write); 1.4861 + MS : R; 1.4862 +%} 1.4863 + 1.4864 +// Memory Nop 1.4865 +pipe_class mem_nop() %{ 1.4866 + single_instruction; 1.4867 + MS : R; 1.4868 +%} 1.4869 + 1.4870 +pipe_class sethi(iRegP dst, immI src) %{ 1.4871 + single_instruction; 1.4872 + dst : E(write); 1.4873 + IALU : R; 1.4874 +%} 1.4875 + 1.4876 +pipe_class loadPollP(iRegP poll) %{ 1.4877 + single_instruction; 1.4878 + poll : R(read); 1.4879 + MS : R; 1.4880 +%} 1.4881 + 1.4882 +pipe_class br(Universe br, label labl) %{ 1.4883 + single_instruction_with_delay_slot; 1.4884 + BR : R; 1.4885 +%} 1.4886 + 1.4887 +pipe_class br_cc(Universe br, cmpOp cmp, flagsReg cr, label labl) %{ 1.4888 + single_instruction_with_delay_slot; 1.4889 + cr : E(read); 1.4890 + BR : R; 1.4891 +%} 1.4892 + 1.4893 +pipe_class br_reg(Universe br, cmpOp cmp, iRegI op1, label labl) %{ 1.4894 + single_instruction_with_delay_slot; 1.4895 + op1 : E(read); 1.4896 + BR : R; 1.4897 + MS : R; 1.4898 +%} 1.4899 + 1.4900 +pipe_class br_fcc(Universe br, cmpOpF cc, flagsReg cr, label labl) %{ 1.4901 + single_instruction_with_delay_slot; 1.4902 + cr : E(read); 1.4903 + BR : R; 1.4904 +%} 1.4905 + 1.4906 +pipe_class br_nop() %{ 1.4907 + single_instruction; 1.4908 + BR : R; 1.4909 +%} 1.4910 + 1.4911 +pipe_class simple_call(method meth) %{ 1.4912 + instruction_count(2); multiple_bundles; force_serialization; 1.4913 + fixed_latency(100); 1.4914 + BR : R(1); 1.4915 + MS : R(1); 1.4916 + A0 : R(1); 1.4917 +%} 1.4918 + 1.4919 +pipe_class compiled_call(method meth) %{ 1.4920 + instruction_count(1); multiple_bundles; force_serialization; 1.4921 + fixed_latency(100); 1.4922 + MS : R(1); 1.4923 +%} 1.4924 + 1.4925 +pipe_class call(method meth) %{ 1.4926 + instruction_count(0); multiple_bundles; force_serialization; 1.4927 + fixed_latency(100); 1.4928 +%} 1.4929 + 1.4930 +pipe_class tail_call(Universe ignore, label labl) %{ 1.4931 + single_instruction; has_delay_slot; 1.4932 + fixed_latency(100); 1.4933 + BR : R(1); 1.4934 + MS : R(1); 1.4935 +%} 1.4936 + 1.4937 +pipe_class ret(Universe ignore) %{ 1.4938 + single_instruction; has_delay_slot; 1.4939 + BR : R(1); 1.4940 + MS : R(1); 1.4941 +%} 1.4942 + 1.4943 +pipe_class ret_poll(g3RegP poll) %{ 1.4944 + instruction_count(3); has_delay_slot; 1.4945 + poll : E(read); 1.4946 + MS : R; 1.4947 +%} 1.4948 + 1.4949 +// The real do-nothing guy 1.4950 +pipe_class empty( ) %{ 1.4951 + instruction_count(0); 1.4952 +%} 1.4953 + 1.4954 +pipe_class long_memory_op() %{ 1.4955 + instruction_count(0); multiple_bundles; force_serialization; 1.4956 + fixed_latency(25); 1.4957 + MS : R(1); 1.4958 +%} 1.4959 + 1.4960 +// Check-cast 1.4961 +pipe_class partial_subtype_check_pipe(Universe ignore, iRegP array, iRegP match ) %{ 1.4962 + array : R(read); 1.4963 + match : R(read); 1.4964 + IALU : R(2); 1.4965 + BR : R(2); 1.4966 + MS : R; 1.4967 +%} 1.4968 + 1.4969 +// Convert FPU flags into +1,0,-1 1.4970 +pipe_class floating_cmp( iRegI dst, regF src1, regF src2 ) %{ 1.4971 + src1 : E(read); 1.4972 + src2 : E(read); 1.4973 + dst : E(write); 1.4974 + FA : R; 1.4975 + MS : R(2); 1.4976 + BR : R(2); 1.4977 +%} 1.4978 + 1.4979 +// Compare for p < q, and conditionally add y 1.4980 +pipe_class cadd_cmpltmask( iRegI p, iRegI q, iRegI y ) %{ 1.4981 + p : E(read); 1.4982 + q : E(read); 1.4983 + y : E(read); 1.4984 + IALU : R(3) 1.4985 +%} 1.4986 + 1.4987 +// Perform a compare, then move conditionally in a branch delay slot. 1.4988 +pipe_class min_max( iRegI src2, iRegI srcdst ) %{ 1.4989 + src2 : E(read); 1.4990 + srcdst : E(read); 1.4991 + IALU : R; 1.4992 + BR : R; 1.4993 +%} 1.4994 + 1.4995 +// Define the class for the Nop node 1.4996 +define %{ 1.4997 + MachNop = ialu_nop; 1.4998 +%} 1.4999 + 1.5000 +%} 1.5001 + 1.5002 +//----------INSTRUCTIONS------------------------------------------------------- 1.5003 + 1.5004 +//------------Special Stack Slot instructions - no match rules----------------- 1.5005 +instruct stkI_to_regF(regF dst, stackSlotI src) %{ 1.5006 + // No match rule to avoid chain rule match. 1.5007 + effect(DEF dst, USE src); 1.5008 + ins_cost(MEMORY_REF_COST); 1.5009 + size(4); 1.5010 + format %{ "LDF $src,$dst\t! stkI to regF" %} 1.5011 + opcode(Assembler::ldf_op3); 1.5012 + ins_encode(form3_mem_reg(src, dst)); 1.5013 + ins_pipe(floadF_stk); 1.5014 +%} 1.5015 + 1.5016 +instruct stkL_to_regD(regD dst, stackSlotL src) %{ 1.5017 + // No match rule to avoid chain rule match. 1.5018 + effect(DEF dst, USE src); 1.5019 + ins_cost(MEMORY_REF_COST); 1.5020 + size(4); 1.5021 + format %{ "LDDF $src,$dst\t! stkL to regD" %} 1.5022 + opcode(Assembler::lddf_op3); 1.5023 + ins_encode(form3_mem_reg(src, dst)); 1.5024 + ins_pipe(floadD_stk); 1.5025 +%} 1.5026 + 1.5027 +instruct regF_to_stkI(stackSlotI dst, regF src) %{ 1.5028 + // No match rule to avoid chain rule match. 1.5029 + effect(DEF dst, USE src); 1.5030 + ins_cost(MEMORY_REF_COST); 1.5031 + size(4); 1.5032 + format %{ "STF $src,$dst\t! regF to stkI" %} 1.5033 + opcode(Assembler::stf_op3); 1.5034 + ins_encode(form3_mem_reg(dst, src)); 1.5035 + ins_pipe(fstoreF_stk_reg); 1.5036 +%} 1.5037 + 1.5038 +instruct regD_to_stkL(stackSlotL dst, regD src) %{ 1.5039 + // No match rule to avoid chain rule match. 1.5040 + effect(DEF dst, USE src); 1.5041 + ins_cost(MEMORY_REF_COST); 1.5042 + size(4); 1.5043 + format %{ "STDF $src,$dst\t! regD to stkL" %} 1.5044 + opcode(Assembler::stdf_op3); 1.5045 + ins_encode(form3_mem_reg(dst, src)); 1.5046 + ins_pipe(fstoreD_stk_reg); 1.5047 +%} 1.5048 + 1.5049 +instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{ 1.5050 + effect(DEF dst, USE src); 1.5051 + ins_cost(MEMORY_REF_COST*2); 1.5052 + size(8); 1.5053 + format %{ "STW $src,$dst.hi\t! long\n\t" 1.5054 + "STW R_G0,$dst.lo" %} 1.5055 + opcode(Assembler::stw_op3); 1.5056 + ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0)); 1.5057 + ins_pipe(lstoreI_stk_reg); 1.5058 +%} 1.5059 + 1.5060 +instruct regL_to_stkD(stackSlotD dst, iRegL src) %{ 1.5061 + // No match rule to avoid chain rule match. 1.5062 + effect(DEF dst, USE src); 1.5063 + ins_cost(MEMORY_REF_COST); 1.5064 + size(4); 1.5065 + format %{ "STX $src,$dst\t! regL to stkD" %} 1.5066 + opcode(Assembler::stx_op3); 1.5067 + ins_encode( form3_mem_reg( dst, src ) ); 1.5068 + ins_pipe(istore_stk_reg); 1.5069 +%} 1.5070 + 1.5071 +//---------- Chain stack slots between similar types -------- 1.5072 + 1.5073 +// Load integer from stack slot 1.5074 +instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{ 1.5075 + match(Set dst src); 1.5076 + ins_cost(MEMORY_REF_COST); 1.5077 + 1.5078 + size(4); 1.5079 + format %{ "LDUW $src,$dst\t!stk" %} 1.5080 + opcode(Assembler::lduw_op3); 1.5081 + ins_encode( form3_mem_reg( src, dst ) ); 1.5082 + ins_pipe(iload_mem); 1.5083 +%} 1.5084 + 1.5085 +// Store integer to stack slot 1.5086 +instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{ 1.5087 + match(Set dst src); 1.5088 + ins_cost(MEMORY_REF_COST); 1.5089 + 1.5090 + size(4); 1.5091 + format %{ "STW $src,$dst\t!stk" %} 1.5092 + opcode(Assembler::stw_op3); 1.5093 + ins_encode( form3_mem_reg( dst, src ) ); 1.5094 + ins_pipe(istore_mem_reg); 1.5095 +%} 1.5096 + 1.5097 +// Load long from stack slot 1.5098 +instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{ 1.5099 + match(Set dst src); 1.5100 + 1.5101 + ins_cost(MEMORY_REF_COST); 1.5102 + size(4); 1.5103 + format %{ "LDX $src,$dst\t! long" %} 1.5104 + opcode(Assembler::ldx_op3); 1.5105 + ins_encode( form3_mem_reg( src, dst ) ); 1.5106 + ins_pipe(iload_mem); 1.5107 +%} 1.5108 + 1.5109 +// Store long to stack slot 1.5110 +instruct regL_to_stkL(stackSlotL dst, iRegL src) %{ 1.5111 + match(Set dst src); 1.5112 + 1.5113 + ins_cost(MEMORY_REF_COST); 1.5114 + size(4); 1.5115 + format %{ "STX $src,$dst\t! long" %} 1.5116 + opcode(Assembler::stx_op3); 1.5117 + ins_encode( form3_mem_reg( dst, src ) ); 1.5118 + ins_pipe(istore_mem_reg); 1.5119 +%} 1.5120 + 1.5121 +#ifdef _LP64 1.5122 +// Load pointer from stack slot, 64-bit encoding 1.5123 +instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ 1.5124 + match(Set dst src); 1.5125 + ins_cost(MEMORY_REF_COST); 1.5126 + size(4); 1.5127 + format %{ "LDX $src,$dst\t!ptr" %} 1.5128 + opcode(Assembler::ldx_op3); 1.5129 + ins_encode( form3_mem_reg( src, dst ) ); 1.5130 + ins_pipe(iload_mem); 1.5131 +%} 1.5132 + 1.5133 +// Store pointer to stack slot 1.5134 +instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ 1.5135 + match(Set dst src); 1.5136 + ins_cost(MEMORY_REF_COST); 1.5137 + size(4); 1.5138 + format %{ "STX $src,$dst\t!ptr" %} 1.5139 + opcode(Assembler::stx_op3); 1.5140 + ins_encode( form3_mem_reg( dst, src ) ); 1.5141 + ins_pipe(istore_mem_reg); 1.5142 +%} 1.5143 +#else // _LP64 1.5144 +// Load pointer from stack slot, 32-bit encoding 1.5145 +instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ 1.5146 + match(Set dst src); 1.5147 + ins_cost(MEMORY_REF_COST); 1.5148 + format %{ "LDUW $src,$dst\t!ptr" %} 1.5149 + opcode(Assembler::lduw_op3, Assembler::ldst_op); 1.5150 + ins_encode( form3_mem_reg( src, dst ) ); 1.5151 + ins_pipe(iload_mem); 1.5152 +%} 1.5153 + 1.5154 +// Store pointer to stack slot 1.5155 +instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ 1.5156 + match(Set dst src); 1.5157 + ins_cost(MEMORY_REF_COST); 1.5158 + format %{ "STW $src,$dst\t!ptr" %} 1.5159 + opcode(Assembler::stw_op3, Assembler::ldst_op); 1.5160 + ins_encode( form3_mem_reg( dst, src ) ); 1.5161 + ins_pipe(istore_mem_reg); 1.5162 +%} 1.5163 +#endif // _LP64 1.5164 + 1.5165 +//------------Special Nop instructions for bundling - no match rules----------- 1.5166 +// Nop using the A0 functional unit 1.5167 +instruct Nop_A0() %{ 1.5168 + ins_cost(0); 1.5169 + 1.5170 + format %{ "NOP ! Alu Pipeline" %} 1.5171 + opcode(Assembler::or_op3, Assembler::arith_op); 1.5172 + ins_encode( form2_nop() ); 1.5173 + ins_pipe(ialu_nop_A0); 1.5174 +%} 1.5175 + 1.5176 +// Nop using the A1 functional unit 1.5177 +instruct Nop_A1( ) %{ 1.5178 + ins_cost(0); 1.5179 + 1.5180 + format %{ "NOP ! Alu Pipeline" %} 1.5181 + opcode(Assembler::or_op3, Assembler::arith_op); 1.5182 + ins_encode( form2_nop() ); 1.5183 + ins_pipe(ialu_nop_A1); 1.5184 +%} 1.5185 + 1.5186 +// Nop using the memory functional unit 1.5187 +instruct Nop_MS( ) %{ 1.5188 + ins_cost(0); 1.5189 + 1.5190 + format %{ "NOP ! Memory Pipeline" %} 1.5191 + ins_encode( emit_mem_nop ); 1.5192 + ins_pipe(mem_nop); 1.5193 +%} 1.5194 + 1.5195 +// Nop using the floating add functional unit 1.5196 +instruct Nop_FA( ) %{ 1.5197 + ins_cost(0); 1.5198 + 1.5199 + format %{ "NOP ! Floating Add Pipeline" %} 1.5200 + ins_encode( emit_fadd_nop ); 1.5201 + ins_pipe(fadd_nop); 1.5202 +%} 1.5203 + 1.5204 +// Nop using the branch functional unit 1.5205 +instruct Nop_BR( ) %{ 1.5206 + ins_cost(0); 1.5207 + 1.5208 + format %{ "NOP ! Branch Pipeline" %} 1.5209 + ins_encode( emit_br_nop ); 1.5210 + ins_pipe(br_nop); 1.5211 +%} 1.5212 + 1.5213 +//----------Load/Store/Move Instructions--------------------------------------- 1.5214 +//----------Load Instructions-------------------------------------------------- 1.5215 +// Load Byte (8bit signed) 1.5216 +instruct loadB(iRegI dst, memory mem) %{ 1.5217 + match(Set dst (LoadB mem)); 1.5218 + ins_cost(MEMORY_REF_COST); 1.5219 + 1.5220 + size(4); 1.5221 + format %{ "LDSB $mem,$dst" %} 1.5222 + opcode(Assembler::ldsb_op3); 1.5223 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5224 + ins_pipe(iload_mask_mem); 1.5225 +%} 1.5226 + 1.5227 +// Load Byte (8bit UNsigned) into an int reg 1.5228 +instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{ 1.5229 + match(Set dst (AndI (LoadB mem) bytemask)); 1.5230 + ins_cost(MEMORY_REF_COST); 1.5231 + 1.5232 + size(4); 1.5233 + format %{ "LDUB $mem,$dst" %} 1.5234 + opcode(Assembler::ldub_op3); 1.5235 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5236 + ins_pipe(iload_mask_mem); 1.5237 +%} 1.5238 + 1.5239 +// Load Byte (8bit UNsigned) into a Long Register 1.5240 +instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{ 1.5241 + match(Set dst (AndL (ConvI2L (LoadB mem)) bytemask)); 1.5242 + ins_cost(MEMORY_REF_COST); 1.5243 + 1.5244 + size(4); 1.5245 + format %{ "LDUB $mem,$dst" %} 1.5246 + opcode(Assembler::ldub_op3); 1.5247 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5248 + ins_pipe(iload_mask_mem); 1.5249 +%} 1.5250 + 1.5251 +// Load Char (16bit UNsigned) into a Long Register 1.5252 +instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{ 1.5253 + match(Set dst (AndL (ConvI2L (LoadC mem)) bytemask)); 1.5254 + ins_cost(MEMORY_REF_COST); 1.5255 + 1.5256 + size(4); 1.5257 + format %{ "LDUH $mem,$dst" %} 1.5258 + opcode(Assembler::lduh_op3); 1.5259 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5260 + ins_pipe(iload_mask_mem); 1.5261 +%} 1.5262 + 1.5263 +// Load Char (16bit unsigned) 1.5264 +instruct loadC(iRegI dst, memory mem) %{ 1.5265 + match(Set dst (LoadC mem)); 1.5266 + ins_cost(MEMORY_REF_COST); 1.5267 + 1.5268 + size(4); 1.5269 + format %{ "LDUH $mem,$dst" %} 1.5270 + opcode(Assembler::lduh_op3); 1.5271 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5272 + ins_pipe(iload_mask_mem); 1.5273 +%} 1.5274 + 1.5275 +// Load Integer 1.5276 +instruct loadI(iRegI dst, memory mem) %{ 1.5277 + match(Set dst (LoadI mem)); 1.5278 + ins_cost(MEMORY_REF_COST); 1.5279 + size(4); 1.5280 + 1.5281 + format %{ "LDUW $mem,$dst" %} 1.5282 + opcode(Assembler::lduw_op3); 1.5283 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5284 + ins_pipe(iload_mem); 1.5285 +%} 1.5286 + 1.5287 +// Load Long - aligned 1.5288 +instruct loadL(iRegL dst, memory mem ) %{ 1.5289 + match(Set dst (LoadL mem)); 1.5290 + ins_cost(MEMORY_REF_COST); 1.5291 + size(4); 1.5292 + format %{ "LDX $mem,$dst\t! long" %} 1.5293 + opcode(Assembler::ldx_op3); 1.5294 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5295 + ins_pipe(iload_mem); 1.5296 +%} 1.5297 + 1.5298 +// Load Long - UNaligned 1.5299 +instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{ 1.5300 + match(Set dst (LoadL_unaligned mem)); 1.5301 + effect(KILL tmp); 1.5302 + ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); 1.5303 + size(16); 1.5304 + format %{ "LDUW $mem+4,R_O7\t! misaligned long\n" 1.5305 + "\tLDUW $mem ,$dst\n" 1.5306 + "\tSLLX #32, $dst, $dst\n" 1.5307 + "\tOR $dst, R_O7, $dst" %} 1.5308 + opcode(Assembler::lduw_op3); 1.5309 + ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst )); 1.5310 + ins_pipe(iload_mem); 1.5311 +%} 1.5312 + 1.5313 +// Load Aligned Packed Byte into a Double Register 1.5314 +instruct loadA8B(regD dst, memory mem) %{ 1.5315 + match(Set dst (Load8B mem)); 1.5316 + ins_cost(MEMORY_REF_COST); 1.5317 + size(4); 1.5318 + format %{ "LDDF $mem,$dst\t! packed8B" %} 1.5319 + opcode(Assembler::lddf_op3); 1.5320 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5321 + ins_pipe(floadD_mem); 1.5322 +%} 1.5323 + 1.5324 +// Load Aligned Packed Char into a Double Register 1.5325 +instruct loadA4C(regD dst, memory mem) %{ 1.5326 + match(Set dst (Load4C mem)); 1.5327 + ins_cost(MEMORY_REF_COST); 1.5328 + size(4); 1.5329 + format %{ "LDDF $mem,$dst\t! packed4C" %} 1.5330 + opcode(Assembler::lddf_op3); 1.5331 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5332 + ins_pipe(floadD_mem); 1.5333 +%} 1.5334 + 1.5335 +// Load Aligned Packed Short into a Double Register 1.5336 +instruct loadA4S(regD dst, memory mem) %{ 1.5337 + match(Set dst (Load4S mem)); 1.5338 + ins_cost(MEMORY_REF_COST); 1.5339 + size(4); 1.5340 + format %{ "LDDF $mem,$dst\t! packed4S" %} 1.5341 + opcode(Assembler::lddf_op3); 1.5342 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5343 + ins_pipe(floadD_mem); 1.5344 +%} 1.5345 + 1.5346 +// Load Aligned Packed Int into a Double Register 1.5347 +instruct loadA2I(regD dst, memory mem) %{ 1.5348 + match(Set dst (Load2I mem)); 1.5349 + ins_cost(MEMORY_REF_COST); 1.5350 + size(4); 1.5351 + format %{ "LDDF $mem,$dst\t! packed2I" %} 1.5352 + opcode(Assembler::lddf_op3); 1.5353 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5354 + ins_pipe(floadD_mem); 1.5355 +%} 1.5356 + 1.5357 +// Load Range 1.5358 +instruct loadRange(iRegI dst, memory mem) %{ 1.5359 + match(Set dst (LoadRange mem)); 1.5360 + ins_cost(MEMORY_REF_COST); 1.5361 + 1.5362 + size(4); 1.5363 + format %{ "LDUW $mem,$dst\t! range" %} 1.5364 + opcode(Assembler::lduw_op3); 1.5365 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5366 + ins_pipe(iload_mem); 1.5367 +%} 1.5368 + 1.5369 +// Load Integer into %f register (for fitos/fitod) 1.5370 +instruct loadI_freg(regF dst, memory mem) %{ 1.5371 + match(Set dst (LoadI mem)); 1.5372 + ins_cost(MEMORY_REF_COST); 1.5373 + size(4); 1.5374 + 1.5375 + format %{ "LDF $mem,$dst\t! for fitos/fitod" %} 1.5376 + opcode(Assembler::ldf_op3); 1.5377 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5378 + ins_pipe(floadF_mem); 1.5379 +%} 1.5380 + 1.5381 +// Load Pointer 1.5382 +instruct loadP(iRegP dst, memory mem) %{ 1.5383 + match(Set dst (LoadP mem)); 1.5384 + ins_cost(MEMORY_REF_COST); 1.5385 + size(4); 1.5386 + 1.5387 +#ifndef _LP64 1.5388 + format %{ "LDUW $mem,$dst\t! ptr" %} 1.5389 + opcode(Assembler::lduw_op3, 0, REGP_OP); 1.5390 +#else 1.5391 + format %{ "LDX $mem,$dst\t! ptr" %} 1.5392 + opcode(Assembler::ldx_op3, 0, REGP_OP); 1.5393 +#endif 1.5394 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5395 + ins_pipe(iload_mem); 1.5396 +%} 1.5397 + 1.5398 +// Load Klass Pointer 1.5399 +instruct loadKlass(iRegP dst, memory mem) %{ 1.5400 + match(Set dst (LoadKlass mem)); 1.5401 + ins_cost(MEMORY_REF_COST); 1.5402 + size(4); 1.5403 + 1.5404 +#ifndef _LP64 1.5405 + format %{ "LDUW $mem,$dst\t! klass ptr" %} 1.5406 + opcode(Assembler::lduw_op3, 0, REGP_OP); 1.5407 +#else 1.5408 + format %{ "LDX $mem,$dst\t! klass ptr" %} 1.5409 + opcode(Assembler::ldx_op3, 0, REGP_OP); 1.5410 +#endif 1.5411 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5412 + ins_pipe(iload_mem); 1.5413 +%} 1.5414 + 1.5415 +// Load Short (16bit signed) 1.5416 +instruct loadS(iRegI dst, memory mem) %{ 1.5417 + match(Set dst (LoadS mem)); 1.5418 + ins_cost(MEMORY_REF_COST); 1.5419 + 1.5420 + size(4); 1.5421 + format %{ "LDSH $mem,$dst" %} 1.5422 + opcode(Assembler::ldsh_op3); 1.5423 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5424 + ins_pipe(iload_mask_mem); 1.5425 +%} 1.5426 + 1.5427 +// Load Double 1.5428 +instruct loadD(regD dst, memory mem) %{ 1.5429 + match(Set dst (LoadD mem)); 1.5430 + ins_cost(MEMORY_REF_COST); 1.5431 + 1.5432 + size(4); 1.5433 + format %{ "LDDF $mem,$dst" %} 1.5434 + opcode(Assembler::lddf_op3); 1.5435 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5436 + ins_pipe(floadD_mem); 1.5437 +%} 1.5438 + 1.5439 +// Load Double - UNaligned 1.5440 +instruct loadD_unaligned(regD_low dst, memory mem ) %{ 1.5441 + match(Set dst (LoadD_unaligned mem)); 1.5442 + ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); 1.5443 + size(8); 1.5444 + format %{ "LDF $mem ,$dst.hi\t! misaligned double\n" 1.5445 + "\tLDF $mem+4,$dst.lo\t!" %} 1.5446 + opcode(Assembler::ldf_op3); 1.5447 + ins_encode( form3_mem_reg_double_unaligned( mem, dst )); 1.5448 + ins_pipe(iload_mem); 1.5449 +%} 1.5450 + 1.5451 +// Load Float 1.5452 +instruct loadF(regF dst, memory mem) %{ 1.5453 + match(Set dst (LoadF mem)); 1.5454 + ins_cost(MEMORY_REF_COST); 1.5455 + 1.5456 + size(4); 1.5457 + format %{ "LDF $mem,$dst" %} 1.5458 + opcode(Assembler::ldf_op3); 1.5459 + ins_encode( form3_mem_reg( mem, dst ) ); 1.5460 + ins_pipe(floadF_mem); 1.5461 +%} 1.5462 + 1.5463 +// Load Constant 1.5464 +instruct loadConI( iRegI dst, immI src ) %{ 1.5465 + match(Set dst src); 1.5466 + ins_cost(DEFAULT_COST * 3/2); 1.5467 + format %{ "SET $src,$dst" %} 1.5468 + ins_encode( Set32(src, dst) ); 1.5469 + ins_pipe(ialu_hi_lo_reg); 1.5470 +%} 1.5471 + 1.5472 +instruct loadConI13( iRegI dst, immI13 src ) %{ 1.5473 + match(Set dst src); 1.5474 + 1.5475 + size(4); 1.5476 + format %{ "MOV $src,$dst" %} 1.5477 + ins_encode( Set13( src, dst ) ); 1.5478 + ins_pipe(ialu_imm); 1.5479 +%} 1.5480 + 1.5481 +instruct loadConP(iRegP dst, immP src) %{ 1.5482 + match(Set dst src); 1.5483 + ins_cost(DEFAULT_COST * 3/2); 1.5484 + format %{ "SET $src,$dst\t!ptr" %} 1.5485 + // This rule does not use "expand" unlike loadConI because then 1.5486 + // the result type is not known to be an Oop. An ADLC 1.5487 + // enhancement will be needed to make that work - not worth it! 1.5488 + 1.5489 + ins_encode( SetPtr( src, dst ) ); 1.5490 + ins_pipe(loadConP); 1.5491 + 1.5492 +%} 1.5493 + 1.5494 +instruct loadConP0(iRegP dst, immP0 src) %{ 1.5495 + match(Set dst src); 1.5496 + 1.5497 + size(4); 1.5498 + format %{ "CLR $dst\t!ptr" %} 1.5499 + ins_encode( SetNull( dst ) ); 1.5500 + ins_pipe(ialu_imm); 1.5501 +%} 1.5502 + 1.5503 +instruct loadConP_poll(iRegP dst, immP_poll src) %{ 1.5504 + match(Set dst src); 1.5505 + ins_cost(DEFAULT_COST); 1.5506 + format %{ "SET $src,$dst\t!ptr" %} 1.5507 + ins_encode %{ 1.5508 + Address polling_page(reg_to_register_object($dst$$reg), (address)os::get_polling_page()); 1.5509 + __ sethi(polling_page, false ); 1.5510 + %} 1.5511 + ins_pipe(loadConP_poll); 1.5512 +%} 1.5513 + 1.5514 +instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ 1.5515 + // %%% maybe this should work like loadConD 1.5516 + match(Set dst src); 1.5517 + effect(KILL tmp); 1.5518 + ins_cost(DEFAULT_COST * 4); 1.5519 + format %{ "SET64 $src,$dst KILL $tmp\t! long" %} 1.5520 + ins_encode( LdImmL(src, dst, tmp) ); 1.5521 + ins_pipe(loadConL); 1.5522 +%} 1.5523 + 1.5524 +instruct loadConL0( iRegL dst, immL0 src ) %{ 1.5525 + match(Set dst src); 1.5526 + ins_cost(DEFAULT_COST); 1.5527 + size(4); 1.5528 + format %{ "CLR $dst\t! long" %} 1.5529 + ins_encode( Set13( src, dst ) ); 1.5530 + ins_pipe(ialu_imm); 1.5531 +%} 1.5532 + 1.5533 +instruct loadConL13( iRegL dst, immL13 src ) %{ 1.5534 + match(Set dst src); 1.5535 + ins_cost(DEFAULT_COST * 2); 1.5536 + 1.5537 + size(4); 1.5538 + format %{ "MOV $src,$dst\t! long" %} 1.5539 + ins_encode( Set13( src, dst ) ); 1.5540 + ins_pipe(ialu_imm); 1.5541 +%} 1.5542 + 1.5543 +instruct loadConF(regF dst, immF src, o7RegP tmp) %{ 1.5544 + match(Set dst src); 1.5545 + effect(KILL tmp); 1.5546 + 1.5547 +#ifdef _LP64 1.5548 + size(36); 1.5549 +#else 1.5550 + size(8); 1.5551 +#endif 1.5552 + 1.5553 + format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t" 1.5554 + "LDF [$tmp+lo(&$src)],$dst" %} 1.5555 + ins_encode( LdImmF(src, dst, tmp) ); 1.5556 + ins_pipe(loadConFD); 1.5557 +%} 1.5558 + 1.5559 +instruct loadConD(regD dst, immD src, o7RegP tmp) %{ 1.5560 + match(Set dst src); 1.5561 + effect(KILL tmp); 1.5562 + 1.5563 +#ifdef _LP64 1.5564 + size(36); 1.5565 +#else 1.5566 + size(8); 1.5567 +#endif 1.5568 + 1.5569 + format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t" 1.5570 + "LDDF [$tmp+lo(&$src)],$dst" %} 1.5571 + ins_encode( LdImmD(src, dst, tmp) ); 1.5572 + ins_pipe(loadConFD); 1.5573 +%} 1.5574 + 1.5575 +// Prefetch instructions. 1.5576 +// Must be safe to execute with invalid address (cannot fault). 1.5577 + 1.5578 +instruct prefetchr( memory mem ) %{ 1.5579 + match( PrefetchRead mem ); 1.5580 + ins_cost(MEMORY_REF_COST); 1.5581 + 1.5582 + format %{ "PREFETCH $mem,0\t! Prefetch read-many" %} 1.5583 + opcode(Assembler::prefetch_op3); 1.5584 + ins_encode( form3_mem_prefetch_read( mem ) ); 1.5585 + ins_pipe(iload_mem); 1.5586 +%} 1.5587 + 1.5588 +instruct prefetchw( memory mem ) %{ 1.5589 + match( PrefetchWrite mem ); 1.5590 + ins_cost(MEMORY_REF_COST); 1.5591 + 1.5592 + format %{ "PREFETCH $mem,2\t! Prefetch write-many (and read)" %} 1.5593 + opcode(Assembler::prefetch_op3); 1.5594 + ins_encode( form3_mem_prefetch_write( mem ) ); 1.5595 + ins_pipe(iload_mem); 1.5596 +%} 1.5597 + 1.5598 + 1.5599 +//----------Store Instructions------------------------------------------------- 1.5600 +// Store Byte 1.5601 +instruct storeB(memory mem, iRegI src) %{ 1.5602 + match(Set mem (StoreB mem src)); 1.5603 + ins_cost(MEMORY_REF_COST); 1.5604 + 1.5605 + size(4); 1.5606 + format %{ "STB $src,$mem\t! byte" %} 1.5607 + opcode(Assembler::stb_op3); 1.5608 + ins_encode( form3_mem_reg( mem, src ) ); 1.5609 + ins_pipe(istore_mem_reg); 1.5610 +%} 1.5611 + 1.5612 +instruct storeB0(memory mem, immI0 src) %{ 1.5613 + match(Set mem (StoreB mem src)); 1.5614 + ins_cost(MEMORY_REF_COST); 1.5615 + 1.5616 + size(4); 1.5617 + format %{ "STB $src,$mem\t! byte" %} 1.5618 + opcode(Assembler::stb_op3); 1.5619 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5620 + ins_pipe(istore_mem_zero); 1.5621 +%} 1.5622 + 1.5623 +instruct storeCM0(memory mem, immI0 src) %{ 1.5624 + match(Set mem (StoreCM mem src)); 1.5625 + ins_cost(MEMORY_REF_COST); 1.5626 + 1.5627 + size(4); 1.5628 + format %{ "STB $src,$mem\t! CMS card-mark byte 0" %} 1.5629 + opcode(Assembler::stb_op3); 1.5630 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5631 + ins_pipe(istore_mem_zero); 1.5632 +%} 1.5633 + 1.5634 +// Store Char/Short 1.5635 +instruct storeC(memory mem, iRegI src) %{ 1.5636 + match(Set mem (StoreC mem src)); 1.5637 + ins_cost(MEMORY_REF_COST); 1.5638 + 1.5639 + size(4); 1.5640 + format %{ "STH $src,$mem\t! short" %} 1.5641 + opcode(Assembler::sth_op3); 1.5642 + ins_encode( form3_mem_reg( mem, src ) ); 1.5643 + ins_pipe(istore_mem_reg); 1.5644 +%} 1.5645 + 1.5646 +instruct storeC0(memory mem, immI0 src) %{ 1.5647 + match(Set mem (StoreC mem src)); 1.5648 + ins_cost(MEMORY_REF_COST); 1.5649 + 1.5650 + size(4); 1.5651 + format %{ "STH $src,$mem\t! short" %} 1.5652 + opcode(Assembler::sth_op3); 1.5653 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5654 + ins_pipe(istore_mem_zero); 1.5655 +%} 1.5656 + 1.5657 +// Store Integer 1.5658 +instruct storeI(memory mem, iRegI src) %{ 1.5659 + match(Set mem (StoreI mem src)); 1.5660 + ins_cost(MEMORY_REF_COST); 1.5661 + 1.5662 + size(4); 1.5663 + format %{ "STW $src,$mem" %} 1.5664 + opcode(Assembler::stw_op3); 1.5665 + ins_encode( form3_mem_reg( mem, src ) ); 1.5666 + ins_pipe(istore_mem_reg); 1.5667 +%} 1.5668 + 1.5669 +// Store Long 1.5670 +instruct storeL(memory mem, iRegL src) %{ 1.5671 + match(Set mem (StoreL mem src)); 1.5672 + ins_cost(MEMORY_REF_COST); 1.5673 + size(4); 1.5674 + format %{ "STX $src,$mem\t! long" %} 1.5675 + opcode(Assembler::stx_op3); 1.5676 + ins_encode( form3_mem_reg( mem, src ) ); 1.5677 + ins_pipe(istore_mem_reg); 1.5678 +%} 1.5679 + 1.5680 +instruct storeI0(memory mem, immI0 src) %{ 1.5681 + match(Set mem (StoreI mem src)); 1.5682 + ins_cost(MEMORY_REF_COST); 1.5683 + 1.5684 + size(4); 1.5685 + format %{ "STW $src,$mem" %} 1.5686 + opcode(Assembler::stw_op3); 1.5687 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5688 + ins_pipe(istore_mem_zero); 1.5689 +%} 1.5690 + 1.5691 +instruct storeL0(memory mem, immL0 src) %{ 1.5692 + match(Set mem (StoreL mem src)); 1.5693 + ins_cost(MEMORY_REF_COST); 1.5694 + 1.5695 + size(4); 1.5696 + format %{ "STX $src,$mem" %} 1.5697 + opcode(Assembler::stx_op3); 1.5698 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5699 + ins_pipe(istore_mem_zero); 1.5700 +%} 1.5701 + 1.5702 +// Store Integer from float register (used after fstoi) 1.5703 +instruct storeI_Freg(memory mem, regF src) %{ 1.5704 + match(Set mem (StoreI mem src)); 1.5705 + ins_cost(MEMORY_REF_COST); 1.5706 + 1.5707 + size(4); 1.5708 + format %{ "STF $src,$mem\t! after fstoi/fdtoi" %} 1.5709 + opcode(Assembler::stf_op3); 1.5710 + ins_encode( form3_mem_reg( mem, src ) ); 1.5711 + ins_pipe(fstoreF_mem_reg); 1.5712 +%} 1.5713 + 1.5714 +// Store Pointer 1.5715 +instruct storeP(memory dst, sp_ptr_RegP src) %{ 1.5716 + match(Set dst (StoreP dst src)); 1.5717 + ins_cost(MEMORY_REF_COST); 1.5718 + size(4); 1.5719 + 1.5720 +#ifndef _LP64 1.5721 + format %{ "STW $src,$dst\t! ptr" %} 1.5722 + opcode(Assembler::stw_op3, 0, REGP_OP); 1.5723 +#else 1.5724 + format %{ "STX $src,$dst\t! ptr" %} 1.5725 + opcode(Assembler::stx_op3, 0, REGP_OP); 1.5726 +#endif 1.5727 + ins_encode( form3_mem_reg( dst, src ) ); 1.5728 + ins_pipe(istore_mem_spORreg); 1.5729 +%} 1.5730 + 1.5731 +instruct storeP0(memory dst, immP0 src) %{ 1.5732 + match(Set dst (StoreP dst src)); 1.5733 + ins_cost(MEMORY_REF_COST); 1.5734 + size(4); 1.5735 + 1.5736 +#ifndef _LP64 1.5737 + format %{ "STW $src,$dst\t! ptr" %} 1.5738 + opcode(Assembler::stw_op3, 0, REGP_OP); 1.5739 +#else 1.5740 + format %{ "STX $src,$dst\t! ptr" %} 1.5741 + opcode(Assembler::stx_op3, 0, REGP_OP); 1.5742 +#endif 1.5743 + ins_encode( form3_mem_reg( dst, R_G0 ) ); 1.5744 + ins_pipe(istore_mem_zero); 1.5745 +%} 1.5746 + 1.5747 +// Store Double 1.5748 +instruct storeD( memory mem, regD src) %{ 1.5749 + match(Set mem (StoreD mem src)); 1.5750 + ins_cost(MEMORY_REF_COST); 1.5751 + 1.5752 + size(4); 1.5753 + format %{ "STDF $src,$mem" %} 1.5754 + opcode(Assembler::stdf_op3); 1.5755 + ins_encode( form3_mem_reg( mem, src ) ); 1.5756 + ins_pipe(fstoreD_mem_reg); 1.5757 +%} 1.5758 + 1.5759 +instruct storeD0( memory mem, immD0 src) %{ 1.5760 + match(Set mem (StoreD mem src)); 1.5761 + ins_cost(MEMORY_REF_COST); 1.5762 + 1.5763 + size(4); 1.5764 + format %{ "STX $src,$mem" %} 1.5765 + opcode(Assembler::stx_op3); 1.5766 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5767 + ins_pipe(fstoreD_mem_zero); 1.5768 +%} 1.5769 + 1.5770 +// Store Float 1.5771 +instruct storeF( memory mem, regF src) %{ 1.5772 + match(Set mem (StoreF mem src)); 1.5773 + ins_cost(MEMORY_REF_COST); 1.5774 + 1.5775 + size(4); 1.5776 + format %{ "STF $src,$mem" %} 1.5777 + opcode(Assembler::stf_op3); 1.5778 + ins_encode( form3_mem_reg( mem, src ) ); 1.5779 + ins_pipe(fstoreF_mem_reg); 1.5780 +%} 1.5781 + 1.5782 +instruct storeF0( memory mem, immF0 src) %{ 1.5783 + match(Set mem (StoreF mem src)); 1.5784 + ins_cost(MEMORY_REF_COST); 1.5785 + 1.5786 + size(4); 1.5787 + format %{ "STW $src,$mem\t! storeF0" %} 1.5788 + opcode(Assembler::stw_op3); 1.5789 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5790 + ins_pipe(fstoreF_mem_zero); 1.5791 +%} 1.5792 + 1.5793 +// Store Aligned Packed Bytes in Double register to memory 1.5794 +instruct storeA8B(memory mem, regD src) %{ 1.5795 + match(Set mem (Store8B mem src)); 1.5796 + ins_cost(MEMORY_REF_COST); 1.5797 + size(4); 1.5798 + format %{ "STDF $src,$mem\t! packed8B" %} 1.5799 + opcode(Assembler::stdf_op3); 1.5800 + ins_encode( form3_mem_reg( mem, src ) ); 1.5801 + ins_pipe(fstoreD_mem_reg); 1.5802 +%} 1.5803 + 1.5804 +// Store Zero into Aligned Packed Bytes 1.5805 +instruct storeA8B0(memory mem, immI0 zero) %{ 1.5806 + match(Set mem (Store8B mem zero)); 1.5807 + ins_cost(MEMORY_REF_COST); 1.5808 + size(4); 1.5809 + format %{ "STX $zero,$mem\t! packed8B" %} 1.5810 + opcode(Assembler::stx_op3); 1.5811 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5812 + ins_pipe(fstoreD_mem_zero); 1.5813 +%} 1.5814 + 1.5815 +// Store Aligned Packed Chars/Shorts in Double register to memory 1.5816 +instruct storeA4C(memory mem, regD src) %{ 1.5817 + match(Set mem (Store4C mem src)); 1.5818 + ins_cost(MEMORY_REF_COST); 1.5819 + size(4); 1.5820 + format %{ "STDF $src,$mem\t! packed4C" %} 1.5821 + opcode(Assembler::stdf_op3); 1.5822 + ins_encode( form3_mem_reg( mem, src ) ); 1.5823 + ins_pipe(fstoreD_mem_reg); 1.5824 +%} 1.5825 + 1.5826 +// Store Zero into Aligned Packed Chars/Shorts 1.5827 +instruct storeA4C0(memory mem, immI0 zero) %{ 1.5828 + match(Set mem (Store4C mem (Replicate4C zero))); 1.5829 + ins_cost(MEMORY_REF_COST); 1.5830 + size(4); 1.5831 + format %{ "STX $zero,$mem\t! packed4C" %} 1.5832 + opcode(Assembler::stx_op3); 1.5833 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5834 + ins_pipe(fstoreD_mem_zero); 1.5835 +%} 1.5836 + 1.5837 +// Store Aligned Packed Ints in Double register to memory 1.5838 +instruct storeA2I(memory mem, regD src) %{ 1.5839 + match(Set mem (Store2I mem src)); 1.5840 + ins_cost(MEMORY_REF_COST); 1.5841 + size(4); 1.5842 + format %{ "STDF $src,$mem\t! packed2I" %} 1.5843 + opcode(Assembler::stdf_op3); 1.5844 + ins_encode( form3_mem_reg( mem, src ) ); 1.5845 + ins_pipe(fstoreD_mem_reg); 1.5846 +%} 1.5847 + 1.5848 +// Store Zero into Aligned Packed Ints 1.5849 +instruct storeA2I0(memory mem, immI0 zero) %{ 1.5850 + match(Set mem (Store2I mem zero)); 1.5851 + ins_cost(MEMORY_REF_COST); 1.5852 + size(4); 1.5853 + format %{ "STX $zero,$mem\t! packed2I" %} 1.5854 + opcode(Assembler::stx_op3); 1.5855 + ins_encode( form3_mem_reg( mem, R_G0 ) ); 1.5856 + ins_pipe(fstoreD_mem_zero); 1.5857 +%} 1.5858 + 1.5859 + 1.5860 +//----------MemBar Instructions----------------------------------------------- 1.5861 +// Memory barrier flavors 1.5862 + 1.5863 +instruct membar_acquire() %{ 1.5864 + match(MemBarAcquire); 1.5865 + ins_cost(4*MEMORY_REF_COST); 1.5866 + 1.5867 + size(0); 1.5868 + format %{ "MEMBAR-acquire" %} 1.5869 + ins_encode( enc_membar_acquire ); 1.5870 + ins_pipe(long_memory_op); 1.5871 +%} 1.5872 + 1.5873 +instruct membar_acquire_lock() %{ 1.5874 + match(MemBarAcquire); 1.5875 + predicate(Matcher::prior_fast_lock(n)); 1.5876 + ins_cost(0); 1.5877 + 1.5878 + size(0); 1.5879 + format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %} 1.5880 + ins_encode( ); 1.5881 + ins_pipe(empty); 1.5882 +%} 1.5883 + 1.5884 +instruct membar_release() %{ 1.5885 + match(MemBarRelease); 1.5886 + ins_cost(4*MEMORY_REF_COST); 1.5887 + 1.5888 + size(0); 1.5889 + format %{ "MEMBAR-release" %} 1.5890 + ins_encode( enc_membar_release ); 1.5891 + ins_pipe(long_memory_op); 1.5892 +%} 1.5893 + 1.5894 +instruct membar_release_lock() %{ 1.5895 + match(MemBarRelease); 1.5896 + predicate(Matcher::post_fast_unlock(n)); 1.5897 + ins_cost(0); 1.5898 + 1.5899 + size(0); 1.5900 + format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %} 1.5901 + ins_encode( ); 1.5902 + ins_pipe(empty); 1.5903 +%} 1.5904 + 1.5905 +instruct membar_volatile() %{ 1.5906 + match(MemBarVolatile); 1.5907 + ins_cost(4*MEMORY_REF_COST); 1.5908 + 1.5909 + size(4); 1.5910 + format %{ "MEMBAR-volatile" %} 1.5911 + ins_encode( enc_membar_volatile ); 1.5912 + ins_pipe(long_memory_op); 1.5913 +%} 1.5914 + 1.5915 +instruct unnecessary_membar_volatile() %{ 1.5916 + match(MemBarVolatile); 1.5917 + predicate(Matcher::post_store_load_barrier(n)); 1.5918 + ins_cost(0); 1.5919 + 1.5920 + size(0); 1.5921 + format %{ "!MEMBAR-volatile (unnecessary so empty encoding)" %} 1.5922 + ins_encode( ); 1.5923 + ins_pipe(empty); 1.5924 +%} 1.5925 + 1.5926 +//----------Register Move Instructions----------------------------------------- 1.5927 +instruct roundDouble_nop(regD dst) %{ 1.5928 + match(Set dst (RoundDouble dst)); 1.5929 + ins_cost(0); 1.5930 + // SPARC results are already "rounded" (i.e., normal-format IEEE) 1.5931 + ins_encode( ); 1.5932 + ins_pipe(empty); 1.5933 +%} 1.5934 + 1.5935 + 1.5936 +instruct roundFloat_nop(regF dst) %{ 1.5937 + match(Set dst (RoundFloat dst)); 1.5938 + ins_cost(0); 1.5939 + // SPARC results are already "rounded" (i.e., normal-format IEEE) 1.5940 + ins_encode( ); 1.5941 + ins_pipe(empty); 1.5942 +%} 1.5943 + 1.5944 + 1.5945 +// Cast Index to Pointer for unsafe natives 1.5946 +instruct castX2P(iRegX src, iRegP dst) %{ 1.5947 + match(Set dst (CastX2P src)); 1.5948 + 1.5949 + format %{ "MOV $src,$dst\t! IntX->Ptr" %} 1.5950 + ins_encode( form3_g0_rs2_rd_move( src, dst ) ); 1.5951 + ins_pipe(ialu_reg); 1.5952 +%} 1.5953 + 1.5954 +// Cast Pointer to Index for unsafe natives 1.5955 +instruct castP2X(iRegP src, iRegX dst) %{ 1.5956 + match(Set dst (CastP2X src)); 1.5957 + 1.5958 + format %{ "MOV $src,$dst\t! Ptr->IntX" %} 1.5959 + ins_encode( form3_g0_rs2_rd_move( src, dst ) ); 1.5960 + ins_pipe(ialu_reg); 1.5961 +%} 1.5962 + 1.5963 +instruct stfSSD(stackSlotD stkSlot, regD src) %{ 1.5964 + // %%%% TO DO: Tell the coalescer that this kind of node is a copy! 1.5965 + match(Set stkSlot src); // chain rule 1.5966 + ins_cost(MEMORY_REF_COST); 1.5967 + format %{ "STDF $src,$stkSlot\t!stk" %} 1.5968 + opcode(Assembler::stdf_op3); 1.5969 + ins_encode(form3_mem_reg(stkSlot, src)); 1.5970 + ins_pipe(fstoreD_stk_reg); 1.5971 +%} 1.5972 + 1.5973 +instruct ldfSSD(regD dst, stackSlotD stkSlot) %{ 1.5974 + // %%%% TO DO: Tell the coalescer that this kind of node is a copy! 1.5975 + match(Set dst stkSlot); // chain rule 1.5976 + ins_cost(MEMORY_REF_COST); 1.5977 + format %{ "LDDF $stkSlot,$dst\t!stk" %} 1.5978 + opcode(Assembler::lddf_op3); 1.5979 + ins_encode(form3_mem_reg(stkSlot, dst)); 1.5980 + ins_pipe(floadD_stk); 1.5981 +%} 1.5982 + 1.5983 +instruct stfSSF(stackSlotF stkSlot, regF src) %{ 1.5984 + // %%%% TO DO: Tell the coalescer that this kind of node is a copy! 1.5985 + match(Set stkSlot src); // chain rule 1.5986 + ins_cost(MEMORY_REF_COST); 1.5987 + format %{ "STF $src,$stkSlot\t!stk" %} 1.5988 + opcode(Assembler::stf_op3); 1.5989 + ins_encode(form3_mem_reg(stkSlot, src)); 1.5990 + ins_pipe(fstoreF_stk_reg); 1.5991 +%} 1.5992 + 1.5993 +//----------Conditional Move--------------------------------------------------- 1.5994 +// Conditional move 1.5995 +instruct cmovIP_reg(cmpOpP cmp, flagsRegP pcc, iRegI dst, iRegI src) %{ 1.5996 + match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src))); 1.5997 + ins_cost(150); 1.5998 + format %{ "MOV$cmp $pcc,$src,$dst" %} 1.5999 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6000 + ins_pipe(ialu_reg); 1.6001 +%} 1.6002 + 1.6003 +instruct cmovIP_imm(cmpOpP cmp, flagsRegP pcc, iRegI dst, immI11 src) %{ 1.6004 + match(Set dst (CMoveI (Binary cmp pcc) (Binary dst src))); 1.6005 + ins_cost(140); 1.6006 + format %{ "MOV$cmp $pcc,$src,$dst" %} 1.6007 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6008 + ins_pipe(ialu_imm); 1.6009 +%} 1.6010 + 1.6011 +instruct cmovII_reg(cmpOp cmp, flagsReg icc, iRegI dst, iRegI src) %{ 1.6012 + match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); 1.6013 + ins_cost(150); 1.6014 + size(4); 1.6015 + format %{ "MOV$cmp $icc,$src,$dst" %} 1.6016 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); 1.6017 + ins_pipe(ialu_reg); 1.6018 +%} 1.6019 + 1.6020 +instruct cmovII_imm(cmpOp cmp, flagsReg icc, iRegI dst, immI11 src) %{ 1.6021 + match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); 1.6022 + ins_cost(140); 1.6023 + size(4); 1.6024 + format %{ "MOV$cmp $icc,$src,$dst" %} 1.6025 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); 1.6026 + ins_pipe(ialu_imm); 1.6027 +%} 1.6028 + 1.6029 +instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{ 1.6030 + match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); 1.6031 + ins_cost(150); 1.6032 + size(4); 1.6033 + format %{ "MOV$cmp $icc,$src,$dst" %} 1.6034 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); 1.6035 + ins_pipe(ialu_reg); 1.6036 +%} 1.6037 + 1.6038 +instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{ 1.6039 + match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); 1.6040 + ins_cost(140); 1.6041 + size(4); 1.6042 + format %{ "MOV$cmp $icc,$src,$dst" %} 1.6043 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); 1.6044 + ins_pipe(ialu_imm); 1.6045 +%} 1.6046 + 1.6047 +instruct cmovIF_reg(cmpOpF cmp, flagsRegF fcc, iRegI dst, iRegI src) %{ 1.6048 + match(Set dst (CMoveI (Binary cmp fcc) (Binary dst src))); 1.6049 + ins_cost(150); 1.6050 + size(4); 1.6051 + format %{ "MOV$cmp $fcc,$src,$dst" %} 1.6052 + ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); 1.6053 + ins_pipe(ialu_reg); 1.6054 +%} 1.6055 + 1.6056 +instruct cmovIF_imm(cmpOpF cmp, flagsRegF fcc, iRegI dst, immI11 src) %{ 1.6057 + match(Set dst (CMoveI (Binary cmp fcc) (Binary dst src))); 1.6058 + ins_cost(140); 1.6059 + size(4); 1.6060 + format %{ "MOV$cmp $fcc,$src,$dst" %} 1.6061 + ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) ); 1.6062 + ins_pipe(ialu_imm); 1.6063 +%} 1.6064 + 1.6065 +// Conditional move 1.6066 +instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{ 1.6067 + match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src))); 1.6068 + ins_cost(150); 1.6069 + format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %} 1.6070 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6071 + ins_pipe(ialu_reg); 1.6072 +%} 1.6073 + 1.6074 +instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{ 1.6075 + match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src))); 1.6076 + ins_cost(140); 1.6077 + format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %} 1.6078 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6079 + ins_pipe(ialu_imm); 1.6080 +%} 1.6081 + 1.6082 +instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{ 1.6083 + match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); 1.6084 + ins_cost(150); 1.6085 + 1.6086 + size(4); 1.6087 + format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} 1.6088 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); 1.6089 + ins_pipe(ialu_reg); 1.6090 +%} 1.6091 + 1.6092 +instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{ 1.6093 + match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); 1.6094 + ins_cost(140); 1.6095 + 1.6096 + size(4); 1.6097 + format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} 1.6098 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); 1.6099 + ins_pipe(ialu_imm); 1.6100 +%} 1.6101 + 1.6102 +instruct cmovPF_reg(cmpOpF cmp, flagsRegF fcc, iRegP dst, iRegP src) %{ 1.6103 + match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src))); 1.6104 + ins_cost(150); 1.6105 + size(4); 1.6106 + format %{ "MOV$cmp $fcc,$src,$dst" %} 1.6107 + ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); 1.6108 + ins_pipe(ialu_imm); 1.6109 +%} 1.6110 + 1.6111 +instruct cmovPF_imm(cmpOpF cmp, flagsRegF fcc, iRegP dst, immP0 src) %{ 1.6112 + match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src))); 1.6113 + ins_cost(140); 1.6114 + size(4); 1.6115 + format %{ "MOV$cmp $fcc,$src,$dst" %} 1.6116 + ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) ); 1.6117 + ins_pipe(ialu_imm); 1.6118 +%} 1.6119 + 1.6120 +// Conditional move 1.6121 +instruct cmovFP_reg(cmpOpP cmp, flagsRegP pcc, regF dst, regF src) %{ 1.6122 + match(Set dst (CMoveF (Binary cmp pcc) (Binary dst src))); 1.6123 + ins_cost(150); 1.6124 + opcode(0x101); 1.6125 + format %{ "FMOVD$cmp $pcc,$src,$dst" %} 1.6126 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6127 + ins_pipe(int_conditional_float_move); 1.6128 +%} 1.6129 + 1.6130 +instruct cmovFI_reg(cmpOp cmp, flagsReg icc, regF dst, regF src) %{ 1.6131 + match(Set dst (CMoveF (Binary cmp icc) (Binary dst src))); 1.6132 + ins_cost(150); 1.6133 + 1.6134 + size(4); 1.6135 + format %{ "FMOVS$cmp $icc,$src,$dst" %} 1.6136 + opcode(0x101); 1.6137 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); 1.6138 + ins_pipe(int_conditional_float_move); 1.6139 +%} 1.6140 + 1.6141 +// Conditional move, 1.6142 +instruct cmovFF_reg(cmpOpF cmp, flagsRegF fcc, regF dst, regF src) %{ 1.6143 + match(Set dst (CMoveF (Binary cmp fcc) (Binary dst src))); 1.6144 + ins_cost(150); 1.6145 + size(4); 1.6146 + format %{ "FMOVF$cmp $fcc,$src,$dst" %} 1.6147 + opcode(0x1); 1.6148 + ins_encode( enc_cmovff_reg(cmp,fcc,dst,src) ); 1.6149 + ins_pipe(int_conditional_double_move); 1.6150 +%} 1.6151 + 1.6152 +// Conditional move 1.6153 +instruct cmovDP_reg(cmpOpP cmp, flagsRegP pcc, regD dst, regD src) %{ 1.6154 + match(Set dst (CMoveD (Binary cmp pcc) (Binary dst src))); 1.6155 + ins_cost(150); 1.6156 + size(4); 1.6157 + opcode(0x102); 1.6158 + format %{ "FMOVD$cmp $pcc,$src,$dst" %} 1.6159 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6160 + ins_pipe(int_conditional_double_move); 1.6161 +%} 1.6162 + 1.6163 +instruct cmovDI_reg(cmpOp cmp, flagsReg icc, regD dst, regD src) %{ 1.6164 + match(Set dst (CMoveD (Binary cmp icc) (Binary dst src))); 1.6165 + ins_cost(150); 1.6166 + 1.6167 + size(4); 1.6168 + format %{ "FMOVD$cmp $icc,$src,$dst" %} 1.6169 + opcode(0x102); 1.6170 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); 1.6171 + ins_pipe(int_conditional_double_move); 1.6172 +%} 1.6173 + 1.6174 +// Conditional move, 1.6175 +instruct cmovDF_reg(cmpOpF cmp, flagsRegF fcc, regD dst, regD src) %{ 1.6176 + match(Set dst (CMoveD (Binary cmp fcc) (Binary dst src))); 1.6177 + ins_cost(150); 1.6178 + size(4); 1.6179 + format %{ "FMOVD$cmp $fcc,$src,$dst" %} 1.6180 + opcode(0x2); 1.6181 + ins_encode( enc_cmovff_reg(cmp,fcc,dst,src) ); 1.6182 + ins_pipe(int_conditional_double_move); 1.6183 +%} 1.6184 + 1.6185 +// Conditional move 1.6186 +instruct cmovLP_reg(cmpOpP cmp, flagsRegP pcc, iRegL dst, iRegL src) %{ 1.6187 + match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src))); 1.6188 + ins_cost(150); 1.6189 + format %{ "MOV$cmp $pcc,$src,$dst\t! long" %} 1.6190 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6191 + ins_pipe(ialu_reg); 1.6192 +%} 1.6193 + 1.6194 +instruct cmovLP_imm(cmpOpP cmp, flagsRegP pcc, iRegL dst, immI11 src) %{ 1.6195 + match(Set dst (CMoveL (Binary cmp pcc) (Binary dst src))); 1.6196 + ins_cost(140); 1.6197 + format %{ "MOV$cmp $pcc,$src,$dst\t! long" %} 1.6198 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) ); 1.6199 + ins_pipe(ialu_imm); 1.6200 +%} 1.6201 + 1.6202 +instruct cmovLI_reg(cmpOp cmp, flagsReg icc, iRegL dst, iRegL src) %{ 1.6203 + match(Set dst (CMoveL (Binary cmp icc) (Binary dst src))); 1.6204 + ins_cost(150); 1.6205 + 1.6206 + size(4); 1.6207 + format %{ "MOV$cmp $icc,$src,$dst\t! long" %} 1.6208 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); 1.6209 + ins_pipe(ialu_reg); 1.6210 +%} 1.6211 + 1.6212 + 1.6213 +instruct cmovLF_reg(cmpOpF cmp, flagsRegF fcc, iRegL dst, iRegL src) %{ 1.6214 + match(Set dst (CMoveL (Binary cmp fcc) (Binary dst src))); 1.6215 + ins_cost(150); 1.6216 + 1.6217 + size(4); 1.6218 + format %{ "MOV$cmp $fcc,$src,$dst\t! long" %} 1.6219 + ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) ); 1.6220 + ins_pipe(ialu_reg); 1.6221 +%} 1.6222 + 1.6223 + 1.6224 + 1.6225 +//----------OS and Locking Instructions---------------------------------------- 1.6226 + 1.6227 +// This name is KNOWN by the ADLC and cannot be changed. 1.6228 +// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 1.6229 +// for this guy. 1.6230 +instruct tlsLoadP(g2RegP dst) %{ 1.6231 + match(Set dst (ThreadLocal)); 1.6232 + 1.6233 + size(0); 1.6234 + ins_cost(0); 1.6235 + format %{ "# TLS is in G2" %} 1.6236 + ins_encode( /*empty encoding*/ ); 1.6237 + ins_pipe(ialu_none); 1.6238 +%} 1.6239 + 1.6240 +instruct checkCastPP( iRegP dst ) %{ 1.6241 + match(Set dst (CheckCastPP dst)); 1.6242 + 1.6243 + size(0); 1.6244 + format %{ "# checkcastPP of $dst" %} 1.6245 + ins_encode( /*empty encoding*/ ); 1.6246 + ins_pipe(empty); 1.6247 +%} 1.6248 + 1.6249 + 1.6250 +instruct castPP( iRegP dst ) %{ 1.6251 + match(Set dst (CastPP dst)); 1.6252 + format %{ "# castPP of $dst" %} 1.6253 + ins_encode( /*empty encoding*/ ); 1.6254 + ins_pipe(empty); 1.6255 +%} 1.6256 + 1.6257 +instruct castII( iRegI dst ) %{ 1.6258 + match(Set dst (CastII dst)); 1.6259 + format %{ "# castII of $dst" %} 1.6260 + ins_encode( /*empty encoding*/ ); 1.6261 + ins_cost(0); 1.6262 + ins_pipe(empty); 1.6263 +%} 1.6264 + 1.6265 +//----------Arithmetic Instructions-------------------------------------------- 1.6266 +// Addition Instructions 1.6267 +// Register Addition 1.6268 +instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6269 + match(Set dst (AddI src1 src2)); 1.6270 + 1.6271 + size(4); 1.6272 + format %{ "ADD $src1,$src2,$dst" %} 1.6273 + ins_encode %{ 1.6274 + __ add($src1$$Register, $src2$$Register, $dst$$Register); 1.6275 + %} 1.6276 + ins_pipe(ialu_reg_reg); 1.6277 +%} 1.6278 + 1.6279 +// Immediate Addition 1.6280 +instruct addI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.6281 + match(Set dst (AddI src1 src2)); 1.6282 + 1.6283 + size(4); 1.6284 + format %{ "ADD $src1,$src2,$dst" %} 1.6285 + opcode(Assembler::add_op3, Assembler::arith_op); 1.6286 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6287 + ins_pipe(ialu_reg_imm); 1.6288 +%} 1.6289 + 1.6290 +// Pointer Register Addition 1.6291 +instruct addP_reg_reg(iRegP dst, iRegP src1, iRegX src2) %{ 1.6292 + match(Set dst (AddP src1 src2)); 1.6293 + 1.6294 + size(4); 1.6295 + format %{ "ADD $src1,$src2,$dst" %} 1.6296 + opcode(Assembler::add_op3, Assembler::arith_op); 1.6297 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6298 + ins_pipe(ialu_reg_reg); 1.6299 +%} 1.6300 + 1.6301 +// Pointer Immediate Addition 1.6302 +instruct addP_reg_imm13(iRegP dst, iRegP src1, immX13 src2) %{ 1.6303 + match(Set dst (AddP src1 src2)); 1.6304 + 1.6305 + size(4); 1.6306 + format %{ "ADD $src1,$src2,$dst" %} 1.6307 + opcode(Assembler::add_op3, Assembler::arith_op); 1.6308 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6309 + ins_pipe(ialu_reg_imm); 1.6310 +%} 1.6311 + 1.6312 +// Long Addition 1.6313 +instruct addL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.6314 + match(Set dst (AddL src1 src2)); 1.6315 + 1.6316 + size(4); 1.6317 + format %{ "ADD $src1,$src2,$dst\t! long" %} 1.6318 + opcode(Assembler::add_op3, Assembler::arith_op); 1.6319 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6320 + ins_pipe(ialu_reg_reg); 1.6321 +%} 1.6322 + 1.6323 +instruct addL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ 1.6324 + match(Set dst (AddL src1 con)); 1.6325 + 1.6326 + size(4); 1.6327 + format %{ "ADD $src1,$con,$dst" %} 1.6328 + opcode(Assembler::add_op3, Assembler::arith_op); 1.6329 + ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); 1.6330 + ins_pipe(ialu_reg_imm); 1.6331 +%} 1.6332 + 1.6333 +//----------Conditional_store-------------------------------------------------- 1.6334 +// Conditional-store of the updated heap-top. 1.6335 +// Used during allocation of the shared heap. 1.6336 +// Sets flags (EQ) on success. Implemented with a CASA on Sparc. 1.6337 + 1.6338 +// LoadP-locked. Same as a regular pointer load when used with a compare-swap 1.6339 +instruct loadPLocked(iRegP dst, memory mem) %{ 1.6340 + match(Set dst (LoadPLocked mem)); 1.6341 + ins_cost(MEMORY_REF_COST); 1.6342 + 1.6343 +#ifndef _LP64 1.6344 + size(4); 1.6345 + format %{ "LDUW $mem,$dst\t! ptr" %} 1.6346 + opcode(Assembler::lduw_op3, 0, REGP_OP); 1.6347 +#else 1.6348 + format %{ "LDX $mem,$dst\t! ptr" %} 1.6349 + opcode(Assembler::ldx_op3, 0, REGP_OP); 1.6350 +#endif 1.6351 + ins_encode( form3_mem_reg( mem, dst ) ); 1.6352 + ins_pipe(iload_mem); 1.6353 +%} 1.6354 + 1.6355 +// LoadL-locked. Same as a regular long load when used with a compare-swap 1.6356 +instruct loadLLocked(iRegL dst, memory mem) %{ 1.6357 + match(Set dst (LoadLLocked mem)); 1.6358 + ins_cost(MEMORY_REF_COST); 1.6359 + size(4); 1.6360 + format %{ "LDX $mem,$dst\t! long" %} 1.6361 + opcode(Assembler::ldx_op3); 1.6362 + ins_encode( form3_mem_reg( mem, dst ) ); 1.6363 + ins_pipe(iload_mem); 1.6364 +%} 1.6365 + 1.6366 +instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{ 1.6367 + match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval))); 1.6368 + effect( KILL newval ); 1.6369 + format %{ "CASA [$heap_top_ptr],$oldval,R_G3\t! If $oldval==[$heap_top_ptr] Then store R_G3 into [$heap_top_ptr], set R_G3=[$heap_top_ptr] in any case\n\t" 1.6370 + "CMP R_G3,$oldval\t\t! See if we made progress" %} 1.6371 + ins_encode( enc_cas(heap_top_ptr,oldval,newval) ); 1.6372 + ins_pipe( long_memory_op ); 1.6373 +%} 1.6374 + 1.6375 +instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ 1.6376 + match(Set res (StoreLConditional mem_ptr (Binary oldval newval))); 1.6377 + effect( USE mem_ptr, KILL ccr, KILL tmp1); 1.6378 + // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap 1.6379 + format %{ 1.6380 + "MOV $newval,R_O7\n\t" 1.6381 + "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t" 1.6382 + "CMP $oldval,R_O7\t\t! See if we made progress\n\t" 1.6383 + "MOV 1,$res\n\t" 1.6384 + "MOVne xcc,R_G0,$res" 1.6385 + %} 1.6386 + ins_encode( enc_casx(mem_ptr, oldval, newval), 1.6387 + enc_lflags_ne_to_boolean(res) ); 1.6388 + ins_pipe( long_memory_op ); 1.6389 +%} 1.6390 + 1.6391 +instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{ 1.6392 + match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero)); 1.6393 + effect( USE mem_ptr, KILL tmp1); 1.6394 + // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap 1.6395 + format %{ 1.6396 + "MOV $newval,R_O7\n\t" 1.6397 + "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t" 1.6398 + "CMP $oldval,R_O7\t\t! See if we made progress" 1.6399 + %} 1.6400 + ins_encode( enc_casx(mem_ptr, oldval, newval)); 1.6401 + ins_pipe( long_memory_op ); 1.6402 +%} 1.6403 + 1.6404 +// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 1.6405 + 1.6406 +instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ 1.6407 + match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 1.6408 + effect( USE mem_ptr, KILL ccr, KILL tmp1); 1.6409 + format %{ 1.6410 + "MOV $newval,O7\n\t" 1.6411 + "CASXA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" 1.6412 + "CMP $oldval,O7\t\t! See if we made progress\n\t" 1.6413 + "MOV 1,$res\n\t" 1.6414 + "MOVne xcc,R_G0,$res" 1.6415 + %} 1.6416 + ins_encode( enc_casx(mem_ptr, oldval, newval), 1.6417 + enc_lflags_ne_to_boolean(res) ); 1.6418 + ins_pipe( long_memory_op ); 1.6419 +%} 1.6420 + 1.6421 + 1.6422 +instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ 1.6423 + match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 1.6424 + effect( USE mem_ptr, KILL ccr, KILL tmp1); 1.6425 + format %{ 1.6426 + "MOV $newval,O7\n\t" 1.6427 + "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" 1.6428 + "CMP $oldval,O7\t\t! See if we made progress\n\t" 1.6429 + "MOV 1,$res\n\t" 1.6430 + "MOVne icc,R_G0,$res" 1.6431 + %} 1.6432 + ins_encode( enc_casi(mem_ptr, oldval, newval), 1.6433 + enc_iflags_ne_to_boolean(res) ); 1.6434 + ins_pipe( long_memory_op ); 1.6435 +%} 1.6436 + 1.6437 +instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ 1.6438 + match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 1.6439 + effect( USE mem_ptr, KILL ccr, KILL tmp1); 1.6440 +#ifdef _LP64 1.6441 + format %{ 1.6442 + "MOV $newval,O7\n\t" 1.6443 + "CASXA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" 1.6444 + "CMP $oldval,O7\t\t! See if we made progress\n\t" 1.6445 + "MOV 1,$res\n\t" 1.6446 + "MOVne xcc,R_G0,$res" 1.6447 + %} 1.6448 + ins_encode( enc_casx(mem_ptr, oldval, newval), 1.6449 + enc_lflags_ne_to_boolean(res) ); 1.6450 +#else 1.6451 + format %{ 1.6452 + "MOV $newval,O7\n\t" 1.6453 + "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" 1.6454 + "CMP $oldval,O7\t\t! See if we made progress\n\t" 1.6455 + "MOV 1,$res\n\t" 1.6456 + "MOVne icc,R_G0,$res" 1.6457 + %} 1.6458 + ins_encode( enc_casi(mem_ptr, oldval, newval), 1.6459 + enc_iflags_ne_to_boolean(res) ); 1.6460 +#endif 1.6461 + ins_pipe( long_memory_op ); 1.6462 +%} 1.6463 + 1.6464 +//--------------------- 1.6465 +// Subtraction Instructions 1.6466 +// Register Subtraction 1.6467 +instruct subI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6468 + match(Set dst (SubI src1 src2)); 1.6469 + 1.6470 + size(4); 1.6471 + format %{ "SUB $src1,$src2,$dst" %} 1.6472 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6473 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6474 + ins_pipe(ialu_reg_reg); 1.6475 +%} 1.6476 + 1.6477 +// Immediate Subtraction 1.6478 +instruct subI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.6479 + match(Set dst (SubI src1 src2)); 1.6480 + 1.6481 + size(4); 1.6482 + format %{ "SUB $src1,$src2,$dst" %} 1.6483 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6484 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6485 + ins_pipe(ialu_reg_imm); 1.6486 +%} 1.6487 + 1.6488 +instruct subI_zero_reg(iRegI dst, immI0 zero, iRegI src2) %{ 1.6489 + match(Set dst (SubI zero src2)); 1.6490 + 1.6491 + size(4); 1.6492 + format %{ "NEG $src2,$dst" %} 1.6493 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6494 + ins_encode( form3_rs1_rs2_rd( R_G0, src2, dst ) ); 1.6495 + ins_pipe(ialu_zero_reg); 1.6496 +%} 1.6497 + 1.6498 +// Long subtraction 1.6499 +instruct subL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.6500 + match(Set dst (SubL src1 src2)); 1.6501 + 1.6502 + size(4); 1.6503 + format %{ "SUB $src1,$src2,$dst\t! long" %} 1.6504 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6505 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6506 + ins_pipe(ialu_reg_reg); 1.6507 +%} 1.6508 + 1.6509 +// Immediate Subtraction 1.6510 +instruct subL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ 1.6511 + match(Set dst (SubL src1 con)); 1.6512 + 1.6513 + size(4); 1.6514 + format %{ "SUB $src1,$con,$dst\t! long" %} 1.6515 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6516 + ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); 1.6517 + ins_pipe(ialu_reg_imm); 1.6518 +%} 1.6519 + 1.6520 +// Long negation 1.6521 +instruct negL_reg_reg(iRegL dst, immL0 zero, iRegL src2) %{ 1.6522 + match(Set dst (SubL zero src2)); 1.6523 + 1.6524 + size(4); 1.6525 + format %{ "NEG $src2,$dst\t! long" %} 1.6526 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6527 + ins_encode( form3_rs1_rs2_rd( R_G0, src2, dst ) ); 1.6528 + ins_pipe(ialu_zero_reg); 1.6529 +%} 1.6530 + 1.6531 +// Multiplication Instructions 1.6532 +// Integer Multiplication 1.6533 +// Register Multiplication 1.6534 +instruct mulI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6535 + match(Set dst (MulI src1 src2)); 1.6536 + 1.6537 + size(4); 1.6538 + format %{ "MULX $src1,$src2,$dst" %} 1.6539 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6540 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6541 + ins_pipe(imul_reg_reg); 1.6542 +%} 1.6543 + 1.6544 +// Immediate Multiplication 1.6545 +instruct mulI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.6546 + match(Set dst (MulI src1 src2)); 1.6547 + 1.6548 + size(4); 1.6549 + format %{ "MULX $src1,$src2,$dst" %} 1.6550 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6551 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6552 + ins_pipe(imul_reg_imm); 1.6553 +%} 1.6554 + 1.6555 +instruct mulL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.6556 + match(Set dst (MulL src1 src2)); 1.6557 + ins_cost(DEFAULT_COST * 5); 1.6558 + size(4); 1.6559 + format %{ "MULX $src1,$src2,$dst\t! long" %} 1.6560 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6561 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6562 + ins_pipe(mulL_reg_reg); 1.6563 +%} 1.6564 + 1.6565 +// Immediate Multiplication 1.6566 +instruct mulL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ 1.6567 + match(Set dst (MulL src1 src2)); 1.6568 + ins_cost(DEFAULT_COST * 5); 1.6569 + size(4); 1.6570 + format %{ "MULX $src1,$src2,$dst" %} 1.6571 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6572 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6573 + ins_pipe(mulL_reg_imm); 1.6574 +%} 1.6575 + 1.6576 +// Integer Division 1.6577 +// Register Division 1.6578 +instruct divI_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ 1.6579 + match(Set dst (DivI src1 src2)); 1.6580 + ins_cost((2+71)*DEFAULT_COST); 1.6581 + 1.6582 + format %{ "SRA $src2,0,$src2\n\t" 1.6583 + "SRA $src1,0,$src1\n\t" 1.6584 + "SDIVX $src1,$src2,$dst" %} 1.6585 + ins_encode( idiv_reg( src1, src2, dst ) ); 1.6586 + ins_pipe(sdiv_reg_reg); 1.6587 +%} 1.6588 + 1.6589 +// Immediate Division 1.6590 +instruct divI_reg_imm13(iRegI dst, iRegIsafe src1, immI13 src2) %{ 1.6591 + match(Set dst (DivI src1 src2)); 1.6592 + ins_cost((2+71)*DEFAULT_COST); 1.6593 + 1.6594 + format %{ "SRA $src1,0,$src1\n\t" 1.6595 + "SDIVX $src1,$src2,$dst" %} 1.6596 + ins_encode( idiv_imm( src1, src2, dst ) ); 1.6597 + ins_pipe(sdiv_reg_imm); 1.6598 +%} 1.6599 + 1.6600 +//----------Div-By-10-Expansion------------------------------------------------ 1.6601 +// Extract hi bits of a 32x32->64 bit multiply. 1.6602 +// Expand rule only, not matched 1.6603 +instruct mul_hi(iRegIsafe dst, iRegIsafe src1, iRegIsafe src2 ) %{ 1.6604 + effect( DEF dst, USE src1, USE src2 ); 1.6605 + format %{ "MULX $src1,$src2,$dst\t! Used in div-by-10\n\t" 1.6606 + "SRLX $dst,#32,$dst\t\t! Extract only hi word of result" %} 1.6607 + ins_encode( enc_mul_hi(dst,src1,src2)); 1.6608 + ins_pipe(sdiv_reg_reg); 1.6609 +%} 1.6610 + 1.6611 +// Magic constant, reciprical of 10 1.6612 +instruct loadConI_x66666667(iRegIsafe dst) %{ 1.6613 + effect( DEF dst ); 1.6614 + 1.6615 + size(8); 1.6616 + format %{ "SET 0x66666667,$dst\t! Used in div-by-10" %} 1.6617 + ins_encode( Set32(0x66666667, dst) ); 1.6618 + ins_pipe(ialu_hi_lo_reg); 1.6619 +%} 1.6620 + 1.6621 +// Register Shift Right Arithmatic Long by 32-63 1.6622 +instruct sra_31( iRegI dst, iRegI src ) %{ 1.6623 + effect( DEF dst, USE src ); 1.6624 + format %{ "SRA $src,31,$dst\t! Used in div-by-10" %} 1.6625 + ins_encode( form3_rs1_rd_copysign_hi(src,dst) ); 1.6626 + ins_pipe(ialu_reg_reg); 1.6627 +%} 1.6628 + 1.6629 +// Arithmetic Shift Right by 8-bit immediate 1.6630 +instruct sra_reg_2( iRegI dst, iRegI src ) %{ 1.6631 + effect( DEF dst, USE src ); 1.6632 + format %{ "SRA $src,2,$dst\t! Used in div-by-10" %} 1.6633 + opcode(Assembler::sra_op3, Assembler::arith_op); 1.6634 + ins_encode( form3_rs1_simm13_rd( src, 0x2, dst ) ); 1.6635 + ins_pipe(ialu_reg_imm); 1.6636 +%} 1.6637 + 1.6638 +// Integer DIV with 10 1.6639 +instruct divI_10( iRegI dst, iRegIsafe src, immI10 div ) %{ 1.6640 + match(Set dst (DivI src div)); 1.6641 + ins_cost((6+6)*DEFAULT_COST); 1.6642 + expand %{ 1.6643 + iRegIsafe tmp1; // Killed temps; 1.6644 + iRegIsafe tmp2; // Killed temps; 1.6645 + iRegI tmp3; // Killed temps; 1.6646 + iRegI tmp4; // Killed temps; 1.6647 + loadConI_x66666667( tmp1 ); // SET 0x66666667 -> tmp1 1.6648 + mul_hi( tmp2, src, tmp1 ); // MUL hibits(src * tmp1) -> tmp2 1.6649 + sra_31( tmp3, src ); // SRA src,31 -> tmp3 1.6650 + sra_reg_2( tmp4, tmp2 ); // SRA tmp2,2 -> tmp4 1.6651 + subI_reg_reg( dst,tmp4,tmp3); // SUB tmp4 - tmp3 -> dst 1.6652 + %} 1.6653 +%} 1.6654 + 1.6655 +// Register Long Division 1.6656 +instruct divL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.6657 + match(Set dst (DivL src1 src2)); 1.6658 + ins_cost(DEFAULT_COST*71); 1.6659 + size(4); 1.6660 + format %{ "SDIVX $src1,$src2,$dst\t! long" %} 1.6661 + opcode(Assembler::sdivx_op3, Assembler::arith_op); 1.6662 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6663 + ins_pipe(divL_reg_reg); 1.6664 +%} 1.6665 + 1.6666 +// Register Long Division 1.6667 +instruct divL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ 1.6668 + match(Set dst (DivL src1 src2)); 1.6669 + ins_cost(DEFAULT_COST*71); 1.6670 + size(4); 1.6671 + format %{ "SDIVX $src1,$src2,$dst\t! long" %} 1.6672 + opcode(Assembler::sdivx_op3, Assembler::arith_op); 1.6673 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6674 + ins_pipe(divL_reg_imm); 1.6675 +%} 1.6676 + 1.6677 +// Integer Remainder 1.6678 +// Register Remainder 1.6679 +instruct modI_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2, o7RegP temp, flagsReg ccr ) %{ 1.6680 + match(Set dst (ModI src1 src2)); 1.6681 + effect( KILL ccr, KILL temp); 1.6682 + 1.6683 + format %{ "SREM $src1,$src2,$dst" %} 1.6684 + ins_encode( irem_reg(src1, src2, dst, temp) ); 1.6685 + ins_pipe(sdiv_reg_reg); 1.6686 +%} 1.6687 + 1.6688 +// Immediate Remainder 1.6689 +instruct modI_reg_imm13(iRegI dst, iRegIsafe src1, immI13 src2, o7RegP temp, flagsReg ccr ) %{ 1.6690 + match(Set dst (ModI src1 src2)); 1.6691 + effect( KILL ccr, KILL temp); 1.6692 + 1.6693 + format %{ "SREM $src1,$src2,$dst" %} 1.6694 + ins_encode( irem_imm(src1, src2, dst, temp) ); 1.6695 + ins_pipe(sdiv_reg_imm); 1.6696 +%} 1.6697 + 1.6698 +// Register Long Remainder 1.6699 +instruct divL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ 1.6700 + effect(DEF dst, USE src1, USE src2); 1.6701 + size(4); 1.6702 + format %{ "SDIVX $src1,$src2,$dst\t! long" %} 1.6703 + opcode(Assembler::sdivx_op3, Assembler::arith_op); 1.6704 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6705 + ins_pipe(divL_reg_reg); 1.6706 +%} 1.6707 + 1.6708 +// Register Long Division 1.6709 +instruct divL_reg_imm13_1(iRegL dst, iRegL src1, immL13 src2) %{ 1.6710 + effect(DEF dst, USE src1, USE src2); 1.6711 + size(4); 1.6712 + format %{ "SDIVX $src1,$src2,$dst\t! long" %} 1.6713 + opcode(Assembler::sdivx_op3, Assembler::arith_op); 1.6714 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6715 + ins_pipe(divL_reg_imm); 1.6716 +%} 1.6717 + 1.6718 +instruct mulL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ 1.6719 + effect(DEF dst, USE src1, USE src2); 1.6720 + size(4); 1.6721 + format %{ "MULX $src1,$src2,$dst\t! long" %} 1.6722 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6723 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6724 + ins_pipe(mulL_reg_reg); 1.6725 +%} 1.6726 + 1.6727 +// Immediate Multiplication 1.6728 +instruct mulL_reg_imm13_1(iRegL dst, iRegL src1, immL13 src2) %{ 1.6729 + effect(DEF dst, USE src1, USE src2); 1.6730 + size(4); 1.6731 + format %{ "MULX $src1,$src2,$dst" %} 1.6732 + opcode(Assembler::mulx_op3, Assembler::arith_op); 1.6733 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.6734 + ins_pipe(mulL_reg_imm); 1.6735 +%} 1.6736 + 1.6737 +instruct subL_reg_reg_1(iRegL dst, iRegL src1, iRegL src2) %{ 1.6738 + effect(DEF dst, USE src1, USE src2); 1.6739 + size(4); 1.6740 + format %{ "SUB $src1,$src2,$dst\t! long" %} 1.6741 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6742 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6743 + ins_pipe(ialu_reg_reg); 1.6744 +%} 1.6745 + 1.6746 +instruct subL_reg_reg_2(iRegL dst, iRegL src1, iRegL src2) %{ 1.6747 + effect(DEF dst, USE src1, USE src2); 1.6748 + size(4); 1.6749 + format %{ "SUB $src1,$src2,$dst\t! long" %} 1.6750 + opcode(Assembler::sub_op3, Assembler::arith_op); 1.6751 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6752 + ins_pipe(ialu_reg_reg); 1.6753 +%} 1.6754 + 1.6755 +// Register Long Remainder 1.6756 +instruct modL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.6757 + match(Set dst (ModL src1 src2)); 1.6758 + ins_cost(DEFAULT_COST*(71 + 6 + 1)); 1.6759 + expand %{ 1.6760 + iRegL tmp1; 1.6761 + iRegL tmp2; 1.6762 + divL_reg_reg_1(tmp1, src1, src2); 1.6763 + mulL_reg_reg_1(tmp2, tmp1, src2); 1.6764 + subL_reg_reg_1(dst, src1, tmp2); 1.6765 + %} 1.6766 +%} 1.6767 + 1.6768 +// Register Long Remainder 1.6769 +instruct modL_reg_imm13(iRegL dst, iRegL src1, immL13 src2) %{ 1.6770 + match(Set dst (ModL src1 src2)); 1.6771 + ins_cost(DEFAULT_COST*(71 + 6 + 1)); 1.6772 + expand %{ 1.6773 + iRegL tmp1; 1.6774 + iRegL tmp2; 1.6775 + divL_reg_imm13_1(tmp1, src1, src2); 1.6776 + mulL_reg_imm13_1(tmp2, tmp1, src2); 1.6777 + subL_reg_reg_2 (dst, src1, tmp2); 1.6778 + %} 1.6779 +%} 1.6780 + 1.6781 +// Integer Shift Instructions 1.6782 +// Register Shift Left 1.6783 +instruct shlI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6784 + match(Set dst (LShiftI src1 src2)); 1.6785 + 1.6786 + size(4); 1.6787 + format %{ "SLL $src1,$src2,$dst" %} 1.6788 + opcode(Assembler::sll_op3, Assembler::arith_op); 1.6789 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6790 + ins_pipe(ialu_reg_reg); 1.6791 +%} 1.6792 + 1.6793 +// Register Shift Left Immediate 1.6794 +instruct shlI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ 1.6795 + match(Set dst (LShiftI src1 src2)); 1.6796 + 1.6797 + size(4); 1.6798 + format %{ "SLL $src1,$src2,$dst" %} 1.6799 + opcode(Assembler::sll_op3, Assembler::arith_op); 1.6800 + ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); 1.6801 + ins_pipe(ialu_reg_imm); 1.6802 +%} 1.6803 + 1.6804 +// Register Shift Left 1.6805 +instruct shlL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ 1.6806 + match(Set dst (LShiftL src1 src2)); 1.6807 + 1.6808 + size(4); 1.6809 + format %{ "SLLX $src1,$src2,$dst" %} 1.6810 + opcode(Assembler::sllx_op3, Assembler::arith_op); 1.6811 + ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); 1.6812 + ins_pipe(ialu_reg_reg); 1.6813 +%} 1.6814 + 1.6815 +// Register Shift Left Immediate 1.6816 +instruct shlL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ 1.6817 + match(Set dst (LShiftL src1 src2)); 1.6818 + 1.6819 + size(4); 1.6820 + format %{ "SLLX $src1,$src2,$dst" %} 1.6821 + opcode(Assembler::sllx_op3, Assembler::arith_op); 1.6822 + ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); 1.6823 + ins_pipe(ialu_reg_imm); 1.6824 +%} 1.6825 + 1.6826 +// Register Arithmetic Shift Right 1.6827 +instruct sarI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6828 + match(Set dst (RShiftI src1 src2)); 1.6829 + size(4); 1.6830 + format %{ "SRA $src1,$src2,$dst" %} 1.6831 + opcode(Assembler::sra_op3, Assembler::arith_op); 1.6832 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6833 + ins_pipe(ialu_reg_reg); 1.6834 +%} 1.6835 + 1.6836 +// Register Arithmetic Shift Right Immediate 1.6837 +instruct sarI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ 1.6838 + match(Set dst (RShiftI src1 src2)); 1.6839 + 1.6840 + size(4); 1.6841 + format %{ "SRA $src1,$src2,$dst" %} 1.6842 + opcode(Assembler::sra_op3, Assembler::arith_op); 1.6843 + ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); 1.6844 + ins_pipe(ialu_reg_imm); 1.6845 +%} 1.6846 + 1.6847 +// Register Shift Right Arithmatic Long 1.6848 +instruct sarL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ 1.6849 + match(Set dst (RShiftL src1 src2)); 1.6850 + 1.6851 + size(4); 1.6852 + format %{ "SRAX $src1,$src2,$dst" %} 1.6853 + opcode(Assembler::srax_op3, Assembler::arith_op); 1.6854 + ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); 1.6855 + ins_pipe(ialu_reg_reg); 1.6856 +%} 1.6857 + 1.6858 +// Register Shift Left Immediate 1.6859 +instruct sarL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ 1.6860 + match(Set dst (RShiftL src1 src2)); 1.6861 + 1.6862 + size(4); 1.6863 + format %{ "SRAX $src1,$src2,$dst" %} 1.6864 + opcode(Assembler::srax_op3, Assembler::arith_op); 1.6865 + ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); 1.6866 + ins_pipe(ialu_reg_imm); 1.6867 +%} 1.6868 + 1.6869 +// Register Shift Right 1.6870 +instruct shrI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.6871 + match(Set dst (URShiftI src1 src2)); 1.6872 + 1.6873 + size(4); 1.6874 + format %{ "SRL $src1,$src2,$dst" %} 1.6875 + opcode(Assembler::srl_op3, Assembler::arith_op); 1.6876 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.6877 + ins_pipe(ialu_reg_reg); 1.6878 +%} 1.6879 + 1.6880 +// Register Shift Right Immediate 1.6881 +instruct shrI_reg_imm5(iRegI dst, iRegI src1, immU5 src2) %{ 1.6882 + match(Set dst (URShiftI src1 src2)); 1.6883 + 1.6884 + size(4); 1.6885 + format %{ "SRL $src1,$src2,$dst" %} 1.6886 + opcode(Assembler::srl_op3, Assembler::arith_op); 1.6887 + ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); 1.6888 + ins_pipe(ialu_reg_imm); 1.6889 +%} 1.6890 + 1.6891 +// Register Shift Right 1.6892 +instruct shrL_reg_reg(iRegL dst, iRegL src1, iRegI src2) %{ 1.6893 + match(Set dst (URShiftL src1 src2)); 1.6894 + 1.6895 + size(4); 1.6896 + format %{ "SRLX $src1,$src2,$dst" %} 1.6897 + opcode(Assembler::srlx_op3, Assembler::arith_op); 1.6898 + ins_encode( form3_sd_rs1_rs2_rd( src1, src2, dst ) ); 1.6899 + ins_pipe(ialu_reg_reg); 1.6900 +%} 1.6901 + 1.6902 +// Register Shift Right Immediate 1.6903 +instruct shrL_reg_imm6(iRegL dst, iRegL src1, immU6 src2) %{ 1.6904 + match(Set dst (URShiftL src1 src2)); 1.6905 + 1.6906 + size(4); 1.6907 + format %{ "SRLX $src1,$src2,$dst" %} 1.6908 + opcode(Assembler::srlx_op3, Assembler::arith_op); 1.6909 + ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); 1.6910 + ins_pipe(ialu_reg_imm); 1.6911 +%} 1.6912 + 1.6913 +// Register Shift Right Immediate with a CastP2X 1.6914 +#ifdef _LP64 1.6915 +instruct shrP_reg_imm6(iRegL dst, iRegP src1, immU6 src2) %{ 1.6916 + match(Set dst (URShiftL (CastP2X src1) src2)); 1.6917 + size(4); 1.6918 + format %{ "SRLX $src1,$src2,$dst\t! Cast ptr $src1 to long and shift" %} 1.6919 + opcode(Assembler::srlx_op3, Assembler::arith_op); 1.6920 + ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) ); 1.6921 + ins_pipe(ialu_reg_imm); 1.6922 +%} 1.6923 +#else 1.6924 +instruct shrP_reg_imm5(iRegI dst, iRegP src1, immU5 src2) %{ 1.6925 + match(Set dst (URShiftI (CastP2X src1) src2)); 1.6926 + size(4); 1.6927 + format %{ "SRL $src1,$src2,$dst\t! Cast ptr $src1 to int and shift" %} 1.6928 + opcode(Assembler::srl_op3, Assembler::arith_op); 1.6929 + ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) ); 1.6930 + ins_pipe(ialu_reg_imm); 1.6931 +%} 1.6932 +#endif 1.6933 + 1.6934 + 1.6935 +//----------Floating Point Arithmetic Instructions----------------------------- 1.6936 + 1.6937 +// Add float single precision 1.6938 +instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 1.6939 + match(Set dst (AddF src1 src2)); 1.6940 + 1.6941 + size(4); 1.6942 + format %{ "FADDS $src1,$src2,$dst" %} 1.6943 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fadds_opf); 1.6944 + ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); 1.6945 + ins_pipe(faddF_reg_reg); 1.6946 +%} 1.6947 + 1.6948 +// Add float double precision 1.6949 +instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 1.6950 + match(Set dst (AddD src1 src2)); 1.6951 + 1.6952 + size(4); 1.6953 + format %{ "FADDD $src1,$src2,$dst" %} 1.6954 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::faddd_opf); 1.6955 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.6956 + ins_pipe(faddD_reg_reg); 1.6957 +%} 1.6958 + 1.6959 +// Sub float single precision 1.6960 +instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 1.6961 + match(Set dst (SubF src1 src2)); 1.6962 + 1.6963 + size(4); 1.6964 + format %{ "FSUBS $src1,$src2,$dst" %} 1.6965 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubs_opf); 1.6966 + ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); 1.6967 + ins_pipe(faddF_reg_reg); 1.6968 +%} 1.6969 + 1.6970 +// Sub float double precision 1.6971 +instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 1.6972 + match(Set dst (SubD src1 src2)); 1.6973 + 1.6974 + size(4); 1.6975 + format %{ "FSUBD $src1,$src2,$dst" %} 1.6976 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubd_opf); 1.6977 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.6978 + ins_pipe(faddD_reg_reg); 1.6979 +%} 1.6980 + 1.6981 +// Mul float single precision 1.6982 +instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 1.6983 + match(Set dst (MulF src1 src2)); 1.6984 + 1.6985 + size(4); 1.6986 + format %{ "FMULS $src1,$src2,$dst" %} 1.6987 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuls_opf); 1.6988 + ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); 1.6989 + ins_pipe(fmulF_reg_reg); 1.6990 +%} 1.6991 + 1.6992 +// Mul float double precision 1.6993 +instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 1.6994 + match(Set dst (MulD src1 src2)); 1.6995 + 1.6996 + size(4); 1.6997 + format %{ "FMULD $src1,$src2,$dst" %} 1.6998 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuld_opf); 1.6999 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.7000 + ins_pipe(fmulD_reg_reg); 1.7001 +%} 1.7002 + 1.7003 +// Div float single precision 1.7004 +instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 1.7005 + match(Set dst (DivF src1 src2)); 1.7006 + 1.7007 + size(4); 1.7008 + format %{ "FDIVS $src1,$src2,$dst" %} 1.7009 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdivs_opf); 1.7010 + ins_encode(form3_opf_rs1F_rs2F_rdF(src1, src2, dst)); 1.7011 + ins_pipe(fdivF_reg_reg); 1.7012 +%} 1.7013 + 1.7014 +// Div float double precision 1.7015 +instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 1.7016 + match(Set dst (DivD src1 src2)); 1.7017 + 1.7018 + size(4); 1.7019 + format %{ "FDIVD $src1,$src2,$dst" %} 1.7020 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdivd_opf); 1.7021 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.7022 + ins_pipe(fdivD_reg_reg); 1.7023 +%} 1.7024 + 1.7025 +// Absolute float double precision 1.7026 +instruct absD_reg(regD dst, regD src) %{ 1.7027 + match(Set dst (AbsD src)); 1.7028 + 1.7029 + format %{ "FABSd $src,$dst" %} 1.7030 + ins_encode(fabsd(dst, src)); 1.7031 + ins_pipe(faddD_reg); 1.7032 +%} 1.7033 + 1.7034 +// Absolute float single precision 1.7035 +instruct absF_reg(regF dst, regF src) %{ 1.7036 + match(Set dst (AbsF src)); 1.7037 + 1.7038 + format %{ "FABSs $src,$dst" %} 1.7039 + ins_encode(fabss(dst, src)); 1.7040 + ins_pipe(faddF_reg); 1.7041 +%} 1.7042 + 1.7043 +instruct negF_reg(regF dst, regF src) %{ 1.7044 + match(Set dst (NegF src)); 1.7045 + 1.7046 + size(4); 1.7047 + format %{ "FNEGs $src,$dst" %} 1.7048 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fnegs_opf); 1.7049 + ins_encode(form3_opf_rs2F_rdF(src, dst)); 1.7050 + ins_pipe(faddF_reg); 1.7051 +%} 1.7052 + 1.7053 +instruct negD_reg(regD dst, regD src) %{ 1.7054 + match(Set dst (NegD src)); 1.7055 + 1.7056 + format %{ "FNEGd $src,$dst" %} 1.7057 + ins_encode(fnegd(dst, src)); 1.7058 + ins_pipe(faddD_reg); 1.7059 +%} 1.7060 + 1.7061 +// Sqrt float double precision 1.7062 +instruct sqrtF_reg_reg(regF dst, regF src) %{ 1.7063 + match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 1.7064 + 1.7065 + size(4); 1.7066 + format %{ "FSQRTS $src,$dst" %} 1.7067 + ins_encode(fsqrts(dst, src)); 1.7068 + ins_pipe(fdivF_reg_reg); 1.7069 +%} 1.7070 + 1.7071 +// Sqrt float double precision 1.7072 +instruct sqrtD_reg_reg(regD dst, regD src) %{ 1.7073 + match(Set dst (SqrtD src)); 1.7074 + 1.7075 + size(4); 1.7076 + format %{ "FSQRTD $src,$dst" %} 1.7077 + ins_encode(fsqrtd(dst, src)); 1.7078 + ins_pipe(fdivD_reg_reg); 1.7079 +%} 1.7080 + 1.7081 +//----------Logical Instructions----------------------------------------------- 1.7082 +// And Instructions 1.7083 +// Register And 1.7084 +instruct andI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.7085 + match(Set dst (AndI src1 src2)); 1.7086 + 1.7087 + size(4); 1.7088 + format %{ "AND $src1,$src2,$dst" %} 1.7089 + opcode(Assembler::and_op3, Assembler::arith_op); 1.7090 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7091 + ins_pipe(ialu_reg_reg); 1.7092 +%} 1.7093 + 1.7094 +// Immediate And 1.7095 +instruct andI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.7096 + match(Set dst (AndI src1 src2)); 1.7097 + 1.7098 + size(4); 1.7099 + format %{ "AND $src1,$src2,$dst" %} 1.7100 + opcode(Assembler::and_op3, Assembler::arith_op); 1.7101 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.7102 + ins_pipe(ialu_reg_imm); 1.7103 +%} 1.7104 + 1.7105 +// Register And Long 1.7106 +instruct andL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.7107 + match(Set dst (AndL src1 src2)); 1.7108 + 1.7109 + ins_cost(DEFAULT_COST); 1.7110 + size(4); 1.7111 + format %{ "AND $src1,$src2,$dst\t! long" %} 1.7112 + opcode(Assembler::and_op3, Assembler::arith_op); 1.7113 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7114 + ins_pipe(ialu_reg_reg); 1.7115 +%} 1.7116 + 1.7117 +instruct andL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ 1.7118 + match(Set dst (AndL src1 con)); 1.7119 + 1.7120 + ins_cost(DEFAULT_COST); 1.7121 + size(4); 1.7122 + format %{ "AND $src1,$con,$dst\t! long" %} 1.7123 + opcode(Assembler::and_op3, Assembler::arith_op); 1.7124 + ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); 1.7125 + ins_pipe(ialu_reg_imm); 1.7126 +%} 1.7127 + 1.7128 +// Or Instructions 1.7129 +// Register Or 1.7130 +instruct orI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.7131 + match(Set dst (OrI src1 src2)); 1.7132 + 1.7133 + size(4); 1.7134 + format %{ "OR $src1,$src2,$dst" %} 1.7135 + opcode(Assembler::or_op3, Assembler::arith_op); 1.7136 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7137 + ins_pipe(ialu_reg_reg); 1.7138 +%} 1.7139 + 1.7140 +// Immediate Or 1.7141 +instruct orI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.7142 + match(Set dst (OrI src1 src2)); 1.7143 + 1.7144 + size(4); 1.7145 + format %{ "OR $src1,$src2,$dst" %} 1.7146 + opcode(Assembler::or_op3, Assembler::arith_op); 1.7147 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.7148 + ins_pipe(ialu_reg_imm); 1.7149 +%} 1.7150 + 1.7151 +// Register Or Long 1.7152 +instruct orL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.7153 + match(Set dst (OrL src1 src2)); 1.7154 + 1.7155 + ins_cost(DEFAULT_COST); 1.7156 + size(4); 1.7157 + format %{ "OR $src1,$src2,$dst\t! long" %} 1.7158 + opcode(Assembler::or_op3, Assembler::arith_op); 1.7159 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7160 + ins_pipe(ialu_reg_reg); 1.7161 +%} 1.7162 + 1.7163 +instruct orL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ 1.7164 + match(Set dst (OrL src1 con)); 1.7165 + ins_cost(DEFAULT_COST*2); 1.7166 + 1.7167 + ins_cost(DEFAULT_COST); 1.7168 + size(4); 1.7169 + format %{ "OR $src1,$con,$dst\t! long" %} 1.7170 + opcode(Assembler::or_op3, Assembler::arith_op); 1.7171 + ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); 1.7172 + ins_pipe(ialu_reg_imm); 1.7173 +%} 1.7174 + 1.7175 +// Xor Instructions 1.7176 +// Register Xor 1.7177 +instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{ 1.7178 + match(Set dst (XorI src1 src2)); 1.7179 + 1.7180 + size(4); 1.7181 + format %{ "XOR $src1,$src2,$dst" %} 1.7182 + opcode(Assembler::xor_op3, Assembler::arith_op); 1.7183 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7184 + ins_pipe(ialu_reg_reg); 1.7185 +%} 1.7186 + 1.7187 +// Immediate Xor 1.7188 +instruct xorI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{ 1.7189 + match(Set dst (XorI src1 src2)); 1.7190 + 1.7191 + size(4); 1.7192 + format %{ "XOR $src1,$src2,$dst" %} 1.7193 + opcode(Assembler::xor_op3, Assembler::arith_op); 1.7194 + ins_encode( form3_rs1_simm13_rd( src1, src2, dst ) ); 1.7195 + ins_pipe(ialu_reg_imm); 1.7196 +%} 1.7197 + 1.7198 +// Register Xor Long 1.7199 +instruct xorL_reg_reg(iRegL dst, iRegL src1, iRegL src2) %{ 1.7200 + match(Set dst (XorL src1 src2)); 1.7201 + 1.7202 + ins_cost(DEFAULT_COST); 1.7203 + size(4); 1.7204 + format %{ "XOR $src1,$src2,$dst\t! long" %} 1.7205 + opcode(Assembler::xor_op3, Assembler::arith_op); 1.7206 + ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) ); 1.7207 + ins_pipe(ialu_reg_reg); 1.7208 +%} 1.7209 + 1.7210 +instruct xorL_reg_imm13(iRegL dst, iRegL src1, immL13 con) %{ 1.7211 + match(Set dst (XorL src1 con)); 1.7212 + 1.7213 + ins_cost(DEFAULT_COST); 1.7214 + size(4); 1.7215 + format %{ "XOR $src1,$con,$dst\t! long" %} 1.7216 + opcode(Assembler::xor_op3, Assembler::arith_op); 1.7217 + ins_encode( form3_rs1_simm13_rd( src1, con, dst ) ); 1.7218 + ins_pipe(ialu_reg_imm); 1.7219 +%} 1.7220 + 1.7221 +//----------Convert to Boolean------------------------------------------------- 1.7222 +// Nice hack for 32-bit tests but doesn't work for 1.7223 +// 64-bit pointers. 1.7224 +instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{ 1.7225 + match(Set dst (Conv2B src)); 1.7226 + effect( KILL ccr ); 1.7227 + ins_cost(DEFAULT_COST*2); 1.7228 + format %{ "CMP R_G0,$src\n\t" 1.7229 + "ADDX R_G0,0,$dst" %} 1.7230 + ins_encode( enc_to_bool( src, dst ) ); 1.7231 + ins_pipe(ialu_reg_ialu); 1.7232 +%} 1.7233 + 1.7234 +#ifndef _LP64 1.7235 +instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{ 1.7236 + match(Set dst (Conv2B src)); 1.7237 + effect( KILL ccr ); 1.7238 + ins_cost(DEFAULT_COST*2); 1.7239 + format %{ "CMP R_G0,$src\n\t" 1.7240 + "ADDX R_G0,0,$dst" %} 1.7241 + ins_encode( enc_to_bool( src, dst ) ); 1.7242 + ins_pipe(ialu_reg_ialu); 1.7243 +%} 1.7244 +#else 1.7245 +instruct convP2B( iRegI dst, iRegP src ) %{ 1.7246 + match(Set dst (Conv2B src)); 1.7247 + ins_cost(DEFAULT_COST*2); 1.7248 + format %{ "MOV $src,$dst\n\t" 1.7249 + "MOVRNZ $src,1,$dst" %} 1.7250 + ins_encode( form3_g0_rs2_rd_move( src, dst ), enc_convP2B( dst, src ) ); 1.7251 + ins_pipe(ialu_clr_and_mover); 1.7252 +%} 1.7253 +#endif 1.7254 + 1.7255 +instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{ 1.7256 + match(Set dst (CmpLTMask p q)); 1.7257 + effect( KILL ccr ); 1.7258 + ins_cost(DEFAULT_COST*4); 1.7259 + format %{ "CMP $p,$q\n\t" 1.7260 + "MOV #0,$dst\n\t" 1.7261 + "BLT,a .+8\n\t" 1.7262 + "MOV #-1,$dst" %} 1.7263 + ins_encode( enc_ltmask(p,q,dst) ); 1.7264 + ins_pipe(ialu_reg_reg_ialu); 1.7265 +%} 1.7266 + 1.7267 +instruct cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{ 1.7268 + match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 1.7269 + effect(KILL ccr, TEMP tmp); 1.7270 + ins_cost(DEFAULT_COST*3); 1.7271 + 1.7272 + format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t" 1.7273 + "ADD $p,$y,$tmp\t! g3=p-q+y\n\t" 1.7274 + "MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %} 1.7275 + ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); 1.7276 + ins_pipe( cadd_cmpltmask ); 1.7277 +%} 1.7278 + 1.7279 +instruct cadd_cmpLTMask2( iRegI p, iRegI q, iRegI y, iRegI tmp, flagsReg ccr ) %{ 1.7280 + match(Set p (AddI (SubI p q) (AndI (CmpLTMask p q) y))); 1.7281 + effect( KILL ccr, TEMP tmp); 1.7282 + ins_cost(DEFAULT_COST*3); 1.7283 + 1.7284 + format %{ "SUBcc $p,$q,$p\t! p' = p-q\n\t" 1.7285 + "ADD $p,$y,$tmp\t! g3=p-q+y\n\t" 1.7286 + "MOVl $tmp,$p\t! p' < 0 ? p'+y : p'" %} 1.7287 + ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); 1.7288 + ins_pipe( cadd_cmpltmask ); 1.7289 +%} 1.7290 + 1.7291 +//----------Arithmetic Conversion Instructions--------------------------------- 1.7292 +// The conversions operations are all Alpha sorted. Please keep it that way! 1.7293 + 1.7294 +instruct convD2F_reg(regF dst, regD src) %{ 1.7295 + match(Set dst (ConvD2F src)); 1.7296 + size(4); 1.7297 + format %{ "FDTOS $src,$dst" %} 1.7298 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fdtos_opf); 1.7299 + ins_encode(form3_opf_rs2D_rdF(src, dst)); 1.7300 + ins_pipe(fcvtD2F); 1.7301 +%} 1.7302 + 1.7303 + 1.7304 +// Convert a double to an int in a float register. 1.7305 +// If the double is a NAN, stuff a zero in instead. 1.7306 +instruct convD2I_helper(regF dst, regD src, flagsRegF0 fcc0) %{ 1.7307 + effect(DEF dst, USE src, KILL fcc0); 1.7308 + format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t" 1.7309 + "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 1.7310 + "FDTOI $src,$dst\t! convert in delay slot\n\t" 1.7311 + "FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t" 1.7312 + "FSUBs $dst,$dst,$dst\t! cleared only if nan\n" 1.7313 + "skip:" %} 1.7314 + ins_encode(form_d2i_helper(src,dst)); 1.7315 + ins_pipe(fcvtD2I); 1.7316 +%} 1.7317 + 1.7318 +instruct convD2I_reg(stackSlotI dst, regD src) %{ 1.7319 + match(Set dst (ConvD2I src)); 1.7320 + ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 1.7321 + expand %{ 1.7322 + regF tmp; 1.7323 + convD2I_helper(tmp, src); 1.7324 + regF_to_stkI(dst, tmp); 1.7325 + %} 1.7326 +%} 1.7327 + 1.7328 +// Convert a double to a long in a double register. 1.7329 +// If the double is a NAN, stuff a zero in instead. 1.7330 +instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{ 1.7331 + effect(DEF dst, USE src, KILL fcc0); 1.7332 + format %{ "FCMPd fcc0,$src,$src\t! check for NAN\n\t" 1.7333 + "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 1.7334 + "FDTOX $src,$dst\t! convert in delay slot\n\t" 1.7335 + "FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t" 1.7336 + "FSUBd $dst,$dst,$dst\t! cleared only if nan\n" 1.7337 + "skip:" %} 1.7338 + ins_encode(form_d2l_helper(src,dst)); 1.7339 + ins_pipe(fcvtD2L); 1.7340 +%} 1.7341 + 1.7342 + 1.7343 +// Double to Long conversion 1.7344 +instruct convD2L_reg(stackSlotL dst, regD src) %{ 1.7345 + match(Set dst (ConvD2L src)); 1.7346 + ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 1.7347 + expand %{ 1.7348 + regD tmp; 1.7349 + convD2L_helper(tmp, src); 1.7350 + regD_to_stkL(dst, tmp); 1.7351 + %} 1.7352 +%} 1.7353 + 1.7354 + 1.7355 +instruct convF2D_reg(regD dst, regF src) %{ 1.7356 + match(Set dst (ConvF2D src)); 1.7357 + format %{ "FSTOD $src,$dst" %} 1.7358 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf); 1.7359 + ins_encode(form3_opf_rs2F_rdD(src, dst)); 1.7360 + ins_pipe(fcvtF2D); 1.7361 +%} 1.7362 + 1.7363 + 1.7364 +instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{ 1.7365 + effect(DEF dst, USE src, KILL fcc0); 1.7366 + format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" 1.7367 + "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 1.7368 + "FSTOI $src,$dst\t! convert in delay slot\n\t" 1.7369 + "FITOS $dst,$dst\t! change NaN/max-int to valid float\n\t" 1.7370 + "FSUBs $dst,$dst,$dst\t! cleared only if nan\n" 1.7371 + "skip:" %} 1.7372 + ins_encode(form_f2i_helper(src,dst)); 1.7373 + ins_pipe(fcvtF2I); 1.7374 +%} 1.7375 + 1.7376 +instruct convF2I_reg(stackSlotI dst, regF src) %{ 1.7377 + match(Set dst (ConvF2I src)); 1.7378 + ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 1.7379 + expand %{ 1.7380 + regF tmp; 1.7381 + convF2I_helper(tmp, src); 1.7382 + regF_to_stkI(dst, tmp); 1.7383 + %} 1.7384 +%} 1.7385 + 1.7386 + 1.7387 +instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{ 1.7388 + effect(DEF dst, USE src, KILL fcc0); 1.7389 + format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" 1.7390 + "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" 1.7391 + "FSTOX $src,$dst\t! convert in delay slot\n\t" 1.7392 + "FXTOD $dst,$dst\t! change NaN/max-long to valid double\n\t" 1.7393 + "FSUBd $dst,$dst,$dst\t! cleared only if nan\n" 1.7394 + "skip:" %} 1.7395 + ins_encode(form_f2l_helper(src,dst)); 1.7396 + ins_pipe(fcvtF2L); 1.7397 +%} 1.7398 + 1.7399 +// Float to Long conversion 1.7400 +instruct convF2L_reg(stackSlotL dst, regF src) %{ 1.7401 + match(Set dst (ConvF2L src)); 1.7402 + ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); 1.7403 + expand %{ 1.7404 + regD tmp; 1.7405 + convF2L_helper(tmp, src); 1.7406 + regD_to_stkL(dst, tmp); 1.7407 + %} 1.7408 +%} 1.7409 + 1.7410 + 1.7411 +instruct convI2D_helper(regD dst, regF tmp) %{ 1.7412 + effect(USE tmp, DEF dst); 1.7413 + format %{ "FITOD $tmp,$dst" %} 1.7414 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); 1.7415 + ins_encode(form3_opf_rs2F_rdD(tmp, dst)); 1.7416 + ins_pipe(fcvtI2D); 1.7417 +%} 1.7418 + 1.7419 +instruct convI2D_reg(stackSlotI src, regD dst) %{ 1.7420 + match(Set dst (ConvI2D src)); 1.7421 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.7422 + expand %{ 1.7423 + regF tmp; 1.7424 + stkI_to_regF( tmp, src); 1.7425 + convI2D_helper( dst, tmp); 1.7426 + %} 1.7427 +%} 1.7428 + 1.7429 +instruct convI2D_mem( regD_low dst, memory mem ) %{ 1.7430 + match(Set dst (ConvI2D (LoadI mem))); 1.7431 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.7432 + size(8); 1.7433 + format %{ "LDF $mem,$dst\n\t" 1.7434 + "FITOD $dst,$dst" %} 1.7435 + opcode(Assembler::ldf_op3, Assembler::fitod_opf); 1.7436 + ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst)); 1.7437 + ins_pipe(floadF_mem); 1.7438 +%} 1.7439 + 1.7440 + 1.7441 +instruct convI2F_helper(regF dst, regF tmp) %{ 1.7442 + effect(DEF dst, USE tmp); 1.7443 + format %{ "FITOS $tmp,$dst" %} 1.7444 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf); 1.7445 + ins_encode(form3_opf_rs2F_rdF(tmp, dst)); 1.7446 + ins_pipe(fcvtI2F); 1.7447 +%} 1.7448 + 1.7449 +instruct convI2F_reg( regF dst, stackSlotI src ) %{ 1.7450 + match(Set dst (ConvI2F src)); 1.7451 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.7452 + expand %{ 1.7453 + regF tmp; 1.7454 + stkI_to_regF(tmp,src); 1.7455 + convI2F_helper(dst, tmp); 1.7456 + %} 1.7457 +%} 1.7458 + 1.7459 +instruct convI2F_mem( regF dst, memory mem ) %{ 1.7460 + match(Set dst (ConvI2F (LoadI mem))); 1.7461 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.7462 + size(8); 1.7463 + format %{ "LDF $mem,$dst\n\t" 1.7464 + "FITOS $dst,$dst" %} 1.7465 + opcode(Assembler::ldf_op3, Assembler::fitos_opf); 1.7466 + ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst)); 1.7467 + ins_pipe(floadF_mem); 1.7468 +%} 1.7469 + 1.7470 + 1.7471 +instruct convI2L_reg(iRegL dst, iRegI src) %{ 1.7472 + match(Set dst (ConvI2L src)); 1.7473 + size(4); 1.7474 + format %{ "SRA $src,0,$dst\t! int->long" %} 1.7475 + opcode(Assembler::sra_op3, Assembler::arith_op); 1.7476 + ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); 1.7477 + ins_pipe(ialu_reg_reg); 1.7478 +%} 1.7479 + 1.7480 +// Zero-extend convert int to long 1.7481 +instruct convI2L_reg_zex(iRegL dst, iRegI src, immL_32bits mask ) %{ 1.7482 + match(Set dst (AndL (ConvI2L src) mask) ); 1.7483 + size(4); 1.7484 + format %{ "SRL $src,0,$dst\t! zero-extend int to long" %} 1.7485 + opcode(Assembler::srl_op3, Assembler::arith_op); 1.7486 + ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); 1.7487 + ins_pipe(ialu_reg_reg); 1.7488 +%} 1.7489 + 1.7490 +// Zero-extend long 1.7491 +instruct zerox_long(iRegL dst, iRegL src, immL_32bits mask ) %{ 1.7492 + match(Set dst (AndL src mask) ); 1.7493 + size(4); 1.7494 + format %{ "SRL $src,0,$dst\t! zero-extend long" %} 1.7495 + opcode(Assembler::srl_op3, Assembler::arith_op); 1.7496 + ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); 1.7497 + ins_pipe(ialu_reg_reg); 1.7498 +%} 1.7499 + 1.7500 +instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{ 1.7501 + match(Set dst (MoveF2I src)); 1.7502 + effect(DEF dst, USE src); 1.7503 + ins_cost(MEMORY_REF_COST); 1.7504 + 1.7505 + size(4); 1.7506 + format %{ "LDUW $src,$dst\t! MoveF2I" %} 1.7507 + opcode(Assembler::lduw_op3); 1.7508 + ins_encode( form3_mem_reg( src, dst ) ); 1.7509 + ins_pipe(iload_mem); 1.7510 +%} 1.7511 + 1.7512 +instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 1.7513 + match(Set dst (MoveI2F src)); 1.7514 + effect(DEF dst, USE src); 1.7515 + ins_cost(MEMORY_REF_COST); 1.7516 + 1.7517 + size(4); 1.7518 + format %{ "LDF $src,$dst\t! MoveI2F" %} 1.7519 + opcode(Assembler::ldf_op3); 1.7520 + ins_encode(form3_mem_reg(src, dst)); 1.7521 + ins_pipe(floadF_stk); 1.7522 +%} 1.7523 + 1.7524 +instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{ 1.7525 + match(Set dst (MoveD2L src)); 1.7526 + effect(DEF dst, USE src); 1.7527 + ins_cost(MEMORY_REF_COST); 1.7528 + 1.7529 + size(4); 1.7530 + format %{ "LDX $src,$dst\t! MoveD2L" %} 1.7531 + opcode(Assembler::ldx_op3); 1.7532 + ins_encode( form3_mem_reg( src, dst ) ); 1.7533 + ins_pipe(iload_mem); 1.7534 +%} 1.7535 + 1.7536 +instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 1.7537 + match(Set dst (MoveL2D src)); 1.7538 + effect(DEF dst, USE src); 1.7539 + ins_cost(MEMORY_REF_COST); 1.7540 + 1.7541 + size(4); 1.7542 + format %{ "LDDF $src,$dst\t! MoveL2D" %} 1.7543 + opcode(Assembler::lddf_op3); 1.7544 + ins_encode(form3_mem_reg(src, dst)); 1.7545 + ins_pipe(floadD_stk); 1.7546 +%} 1.7547 + 1.7548 +instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 1.7549 + match(Set dst (MoveF2I src)); 1.7550 + effect(DEF dst, USE src); 1.7551 + ins_cost(MEMORY_REF_COST); 1.7552 + 1.7553 + size(4); 1.7554 + format %{ "STF $src,$dst\t!MoveF2I" %} 1.7555 + opcode(Assembler::stf_op3); 1.7556 + ins_encode(form3_mem_reg(dst, src)); 1.7557 + ins_pipe(fstoreF_stk_reg); 1.7558 +%} 1.7559 + 1.7560 +instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 1.7561 + match(Set dst (MoveI2F src)); 1.7562 + effect(DEF dst, USE src); 1.7563 + ins_cost(MEMORY_REF_COST); 1.7564 + 1.7565 + size(4); 1.7566 + format %{ "STW $src,$dst\t!MoveI2F" %} 1.7567 + opcode(Assembler::stw_op3); 1.7568 + ins_encode( form3_mem_reg( dst, src ) ); 1.7569 + ins_pipe(istore_mem_reg); 1.7570 +%} 1.7571 + 1.7572 +instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 1.7573 + match(Set dst (MoveD2L src)); 1.7574 + effect(DEF dst, USE src); 1.7575 + ins_cost(MEMORY_REF_COST); 1.7576 + 1.7577 + size(4); 1.7578 + format %{ "STDF $src,$dst\t!MoveD2L" %} 1.7579 + opcode(Assembler::stdf_op3); 1.7580 + ins_encode(form3_mem_reg(dst, src)); 1.7581 + ins_pipe(fstoreD_stk_reg); 1.7582 +%} 1.7583 + 1.7584 +instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 1.7585 + match(Set dst (MoveL2D src)); 1.7586 + effect(DEF dst, USE src); 1.7587 + ins_cost(MEMORY_REF_COST); 1.7588 + 1.7589 + size(4); 1.7590 + format %{ "STX $src,$dst\t!MoveL2D" %} 1.7591 + opcode(Assembler::stx_op3); 1.7592 + ins_encode( form3_mem_reg( dst, src ) ); 1.7593 + ins_pipe(istore_mem_reg); 1.7594 +%} 1.7595 + 1.7596 + 1.7597 +//----------- 1.7598 +// Long to Double conversion using V8 opcodes. 1.7599 +// Still useful because cheetah traps and becomes 1.7600 +// amazingly slow for some common numbers. 1.7601 + 1.7602 +// Magic constant, 0x43300000 1.7603 +instruct loadConI_x43300000(iRegI dst) %{ 1.7604 + effect(DEF dst); 1.7605 + size(4); 1.7606 + format %{ "SETHI HI(0x43300000),$dst\t! 2^52" %} 1.7607 + ins_encode(SetHi22(0x43300000, dst)); 1.7608 + ins_pipe(ialu_none); 1.7609 +%} 1.7610 + 1.7611 +// Magic constant, 0x41f00000 1.7612 +instruct loadConI_x41f00000(iRegI dst) %{ 1.7613 + effect(DEF dst); 1.7614 + size(4); 1.7615 + format %{ "SETHI HI(0x41f00000),$dst\t! 2^32" %} 1.7616 + ins_encode(SetHi22(0x41f00000, dst)); 1.7617 + ins_pipe(ialu_none); 1.7618 +%} 1.7619 + 1.7620 +// Construct a double from two float halves 1.7621 +instruct regDHi_regDLo_to_regD(regD_low dst, regD_low src1, regD_low src2) %{ 1.7622 + effect(DEF dst, USE src1, USE src2); 1.7623 + size(8); 1.7624 + format %{ "FMOVS $src1.hi,$dst.hi\n\t" 1.7625 + "FMOVS $src2.lo,$dst.lo" %} 1.7626 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmovs_opf); 1.7627 + ins_encode(form3_opf_rs2D_hi_rdD_hi(src1, dst), form3_opf_rs2D_lo_rdD_lo(src2, dst)); 1.7628 + ins_pipe(faddD_reg_reg); 1.7629 +%} 1.7630 + 1.7631 +// Convert integer in high half of a double register (in the lower half of 1.7632 +// the double register file) to double 1.7633 +instruct convI2D_regDHi_regD(regD dst, regD_low src) %{ 1.7634 + effect(DEF dst, USE src); 1.7635 + size(4); 1.7636 + format %{ "FITOD $src,$dst" %} 1.7637 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); 1.7638 + ins_encode(form3_opf_rs2D_rdD(src, dst)); 1.7639 + ins_pipe(fcvtLHi2D); 1.7640 +%} 1.7641 + 1.7642 +// Add float double precision 1.7643 +instruct addD_regD_regD(regD dst, regD src1, regD src2) %{ 1.7644 + effect(DEF dst, USE src1, USE src2); 1.7645 + size(4); 1.7646 + format %{ "FADDD $src1,$src2,$dst" %} 1.7647 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::faddd_opf); 1.7648 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.7649 + ins_pipe(faddD_reg_reg); 1.7650 +%} 1.7651 + 1.7652 +// Sub float double precision 1.7653 +instruct subD_regD_regD(regD dst, regD src1, regD src2) %{ 1.7654 + effect(DEF dst, USE src1, USE src2); 1.7655 + size(4); 1.7656 + format %{ "FSUBD $src1,$src2,$dst" %} 1.7657 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fsubd_opf); 1.7658 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.7659 + ins_pipe(faddD_reg_reg); 1.7660 +%} 1.7661 + 1.7662 +// Mul float double precision 1.7663 +instruct mulD_regD_regD(regD dst, regD src1, regD src2) %{ 1.7664 + effect(DEF dst, USE src1, USE src2); 1.7665 + size(4); 1.7666 + format %{ "FMULD $src1,$src2,$dst" %} 1.7667 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fmuld_opf); 1.7668 + ins_encode(form3_opf_rs1D_rs2D_rdD(src1, src2, dst)); 1.7669 + ins_pipe(fmulD_reg_reg); 1.7670 +%} 1.7671 + 1.7672 +instruct convL2D_reg_slow_fxtof(regD dst, stackSlotL src) %{ 1.7673 + match(Set dst (ConvL2D src)); 1.7674 + ins_cost(DEFAULT_COST*8 + MEMORY_REF_COST*6); 1.7675 + 1.7676 + expand %{ 1.7677 + regD_low tmpsrc; 1.7678 + iRegI ix43300000; 1.7679 + iRegI ix41f00000; 1.7680 + stackSlotL lx43300000; 1.7681 + stackSlotL lx41f00000; 1.7682 + regD_low dx43300000; 1.7683 + regD dx41f00000; 1.7684 + regD tmp1; 1.7685 + regD_low tmp2; 1.7686 + regD tmp3; 1.7687 + regD tmp4; 1.7688 + 1.7689 + stkL_to_regD(tmpsrc, src); 1.7690 + 1.7691 + loadConI_x43300000(ix43300000); 1.7692 + loadConI_x41f00000(ix41f00000); 1.7693 + regI_to_stkLHi(lx43300000, ix43300000); 1.7694 + regI_to_stkLHi(lx41f00000, ix41f00000); 1.7695 + stkL_to_regD(dx43300000, lx43300000); 1.7696 + stkL_to_regD(dx41f00000, lx41f00000); 1.7697 + 1.7698 + convI2D_regDHi_regD(tmp1, tmpsrc); 1.7699 + regDHi_regDLo_to_regD(tmp2, dx43300000, tmpsrc); 1.7700 + subD_regD_regD(tmp3, tmp2, dx43300000); 1.7701 + mulD_regD_regD(tmp4, tmp1, dx41f00000); 1.7702 + addD_regD_regD(dst, tmp3, tmp4); 1.7703 + %} 1.7704 +%} 1.7705 + 1.7706 +// Long to Double conversion using fast fxtof 1.7707 +instruct convL2D_helper(regD dst, regD tmp) %{ 1.7708 + effect(DEF dst, USE tmp); 1.7709 + size(4); 1.7710 + format %{ "FXTOD $tmp,$dst" %} 1.7711 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf); 1.7712 + ins_encode(form3_opf_rs2D_rdD(tmp, dst)); 1.7713 + ins_pipe(fcvtL2D); 1.7714 +%} 1.7715 + 1.7716 +instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{ 1.7717 + predicate(VM_Version::has_fast_fxtof()); 1.7718 + match(Set dst (ConvL2D src)); 1.7719 + ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST); 1.7720 + expand %{ 1.7721 + regD tmp; 1.7722 + stkL_to_regD(tmp, src); 1.7723 + convL2D_helper(dst, tmp); 1.7724 + %} 1.7725 +%} 1.7726 + 1.7727 +//----------- 1.7728 +// Long to Float conversion using V8 opcodes. 1.7729 +// Still useful because cheetah traps and becomes 1.7730 +// amazingly slow for some common numbers. 1.7731 + 1.7732 +// Long to Float conversion using fast fxtof 1.7733 +instruct convL2F_helper(regF dst, regD tmp) %{ 1.7734 + effect(DEF dst, USE tmp); 1.7735 + size(4); 1.7736 + format %{ "FXTOS $tmp,$dst" %} 1.7737 + opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf); 1.7738 + ins_encode(form3_opf_rs2D_rdF(tmp, dst)); 1.7739 + ins_pipe(fcvtL2F); 1.7740 +%} 1.7741 + 1.7742 +instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{ 1.7743 + match(Set dst (ConvL2F src)); 1.7744 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.7745 + expand %{ 1.7746 + regD tmp; 1.7747 + stkL_to_regD(tmp, src); 1.7748 + convL2F_helper(dst, tmp); 1.7749 + %} 1.7750 +%} 1.7751 +//----------- 1.7752 + 1.7753 +instruct convL2I_reg(iRegI dst, iRegL src) %{ 1.7754 + match(Set dst (ConvL2I src)); 1.7755 +#ifndef _LP64 1.7756 + format %{ "MOV $src.lo,$dst\t! long->int" %} 1.7757 + ins_encode( form3_g0_rs2_rd_move_lo2( src, dst ) ); 1.7758 + ins_pipe(ialu_move_reg_I_to_L); 1.7759 +#else 1.7760 + size(4); 1.7761 + format %{ "SRA $src,R_G0,$dst\t! long->int" %} 1.7762 + ins_encode( form3_rs1_rd_signextend_lo1( src, dst ) ); 1.7763 + ins_pipe(ialu_reg); 1.7764 +#endif 1.7765 +%} 1.7766 + 1.7767 +// Register Shift Right Immediate 1.7768 +instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{ 1.7769 + match(Set dst (ConvL2I (RShiftL src cnt))); 1.7770 + 1.7771 + size(4); 1.7772 + format %{ "SRAX $src,$cnt,$dst" %} 1.7773 + opcode(Assembler::srax_op3, Assembler::arith_op); 1.7774 + ins_encode( form3_sd_rs1_imm6_rd( src, cnt, dst ) ); 1.7775 + ins_pipe(ialu_reg_imm); 1.7776 +%} 1.7777 + 1.7778 +// Replicate scalar to packed byte values in Double register 1.7779 +instruct Repl8B_reg_helper(iRegL dst, iRegI src) %{ 1.7780 + effect(DEF dst, USE src); 1.7781 + format %{ "SLLX $src,56,$dst\n\t" 1.7782 + "SRLX $dst, 8,O7\n\t" 1.7783 + "OR $dst,O7,$dst\n\t" 1.7784 + "SRLX $dst,16,O7\n\t" 1.7785 + "OR $dst,O7,$dst\n\t" 1.7786 + "SRLX $dst,32,O7\n\t" 1.7787 + "OR $dst,O7,$dst\t! replicate8B" %} 1.7788 + ins_encode( enc_repl8b(src, dst)); 1.7789 + ins_pipe(ialu_reg); 1.7790 +%} 1.7791 + 1.7792 +// Replicate scalar to packed byte values in Double register 1.7793 +instruct Repl8B_reg(stackSlotD dst, iRegI src) %{ 1.7794 + match(Set dst (Replicate8B src)); 1.7795 + expand %{ 1.7796 + iRegL tmp; 1.7797 + Repl8B_reg_helper(tmp, src); 1.7798 + regL_to_stkD(dst, tmp); 1.7799 + %} 1.7800 +%} 1.7801 + 1.7802 +// Replicate scalar constant to packed byte values in Double register 1.7803 +instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{ 1.7804 + match(Set dst (Replicate8B src)); 1.7805 +#ifdef _LP64 1.7806 + size(36); 1.7807 +#else 1.7808 + size(8); 1.7809 +#endif 1.7810 + format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t" 1.7811 + "LDDF [$tmp+lo(&Repl8($src))],$dst" %} 1.7812 + ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) ); 1.7813 + ins_pipe(loadConFD); 1.7814 +%} 1.7815 + 1.7816 +// Replicate scalar to packed char values into stack slot 1.7817 +instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{ 1.7818 + effect(DEF dst, USE src); 1.7819 + format %{ "SLLX $src,48,$dst\n\t" 1.7820 + "SRLX $dst,16,O7\n\t" 1.7821 + "OR $dst,O7,$dst\n\t" 1.7822 + "SRLX $dst,32,O7\n\t" 1.7823 + "OR $dst,O7,$dst\t! replicate4C" %} 1.7824 + ins_encode( enc_repl4s(src, dst) ); 1.7825 + ins_pipe(ialu_reg); 1.7826 +%} 1.7827 + 1.7828 +// Replicate scalar to packed char values into stack slot 1.7829 +instruct Repl4C_reg(stackSlotD dst, iRegI src) %{ 1.7830 + match(Set dst (Replicate4C src)); 1.7831 + expand %{ 1.7832 + iRegL tmp; 1.7833 + Repl4C_reg_helper(tmp, src); 1.7834 + regL_to_stkD(dst, tmp); 1.7835 + %} 1.7836 +%} 1.7837 + 1.7838 +// Replicate scalar constant to packed char values in Double register 1.7839 +instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{ 1.7840 + match(Set dst (Replicate4C src)); 1.7841 +#ifdef _LP64 1.7842 + size(36); 1.7843 +#else 1.7844 + size(8); 1.7845 +#endif 1.7846 + format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t" 1.7847 + "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 1.7848 + ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 1.7849 + ins_pipe(loadConFD); 1.7850 +%} 1.7851 + 1.7852 +// Replicate scalar to packed short values into stack slot 1.7853 +instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{ 1.7854 + effect(DEF dst, USE src); 1.7855 + format %{ "SLLX $src,48,$dst\n\t" 1.7856 + "SRLX $dst,16,O7\n\t" 1.7857 + "OR $dst,O7,$dst\n\t" 1.7858 + "SRLX $dst,32,O7\n\t" 1.7859 + "OR $dst,O7,$dst\t! replicate4S" %} 1.7860 + ins_encode( enc_repl4s(src, dst) ); 1.7861 + ins_pipe(ialu_reg); 1.7862 +%} 1.7863 + 1.7864 +// Replicate scalar to packed short values into stack slot 1.7865 +instruct Repl4S_reg(stackSlotD dst, iRegI src) %{ 1.7866 + match(Set dst (Replicate4S src)); 1.7867 + expand %{ 1.7868 + iRegL tmp; 1.7869 + Repl4S_reg_helper(tmp, src); 1.7870 + regL_to_stkD(dst, tmp); 1.7871 + %} 1.7872 +%} 1.7873 + 1.7874 +// Replicate scalar constant to packed short values in Double register 1.7875 +instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{ 1.7876 + match(Set dst (Replicate4S src)); 1.7877 +#ifdef _LP64 1.7878 + size(36); 1.7879 +#else 1.7880 + size(8); 1.7881 +#endif 1.7882 + format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t" 1.7883 + "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 1.7884 + ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 1.7885 + ins_pipe(loadConFD); 1.7886 +%} 1.7887 + 1.7888 +// Replicate scalar to packed int values in Double register 1.7889 +instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{ 1.7890 + effect(DEF dst, USE src); 1.7891 + format %{ "SLLX $src,32,$dst\n\t" 1.7892 + "SRLX $dst,32,O7\n\t" 1.7893 + "OR $dst,O7,$dst\t! replicate2I" %} 1.7894 + ins_encode( enc_repl2i(src, dst)); 1.7895 + ins_pipe(ialu_reg); 1.7896 +%} 1.7897 + 1.7898 +// Replicate scalar to packed int values in Double register 1.7899 +instruct Repl2I_reg(stackSlotD dst, iRegI src) %{ 1.7900 + match(Set dst (Replicate2I src)); 1.7901 + expand %{ 1.7902 + iRegL tmp; 1.7903 + Repl2I_reg_helper(tmp, src); 1.7904 + regL_to_stkD(dst, tmp); 1.7905 + %} 1.7906 +%} 1.7907 + 1.7908 +// Replicate scalar zero constant to packed int values in Double register 1.7909 +instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{ 1.7910 + match(Set dst (Replicate2I src)); 1.7911 +#ifdef _LP64 1.7912 + size(36); 1.7913 +#else 1.7914 + size(8); 1.7915 +#endif 1.7916 + format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t" 1.7917 + "LDDF [$tmp+lo(&Repl2($src))],$dst" %} 1.7918 + ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) ); 1.7919 + ins_pipe(loadConFD); 1.7920 +%} 1.7921 + 1.7922 +//----------Control Flow Instructions------------------------------------------ 1.7923 +// Compare Instructions 1.7924 +// Compare Integers 1.7925 +instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{ 1.7926 + match(Set icc (CmpI op1 op2)); 1.7927 + effect( DEF icc, USE op1, USE op2 ); 1.7928 + 1.7929 + size(4); 1.7930 + format %{ "CMP $op1,$op2" %} 1.7931 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.7932 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.7933 + ins_pipe(ialu_cconly_reg_reg); 1.7934 +%} 1.7935 + 1.7936 +instruct compU_iReg(flagsRegU icc, iRegI op1, iRegI op2) %{ 1.7937 + match(Set icc (CmpU op1 op2)); 1.7938 + 1.7939 + size(4); 1.7940 + format %{ "CMP $op1,$op2\t! unsigned" %} 1.7941 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.7942 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.7943 + ins_pipe(ialu_cconly_reg_reg); 1.7944 +%} 1.7945 + 1.7946 +instruct compI_iReg_imm13(flagsReg icc, iRegI op1, immI13 op2) %{ 1.7947 + match(Set icc (CmpI op1 op2)); 1.7948 + effect( DEF icc, USE op1 ); 1.7949 + 1.7950 + size(4); 1.7951 + format %{ "CMP $op1,$op2" %} 1.7952 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.7953 + ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); 1.7954 + ins_pipe(ialu_cconly_reg_imm); 1.7955 +%} 1.7956 + 1.7957 +instruct testI_reg_reg( flagsReg icc, iRegI op1, iRegI op2, immI0 zero ) %{ 1.7958 + match(Set icc (CmpI (AndI op1 op2) zero)); 1.7959 + 1.7960 + size(4); 1.7961 + format %{ "BTST $op2,$op1" %} 1.7962 + opcode(Assembler::andcc_op3, Assembler::arith_op); 1.7963 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.7964 + ins_pipe(ialu_cconly_reg_reg_zero); 1.7965 +%} 1.7966 + 1.7967 +instruct testI_reg_imm( flagsReg icc, iRegI op1, immI13 op2, immI0 zero ) %{ 1.7968 + match(Set icc (CmpI (AndI op1 op2) zero)); 1.7969 + 1.7970 + size(4); 1.7971 + format %{ "BTST $op2,$op1" %} 1.7972 + opcode(Assembler::andcc_op3, Assembler::arith_op); 1.7973 + ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); 1.7974 + ins_pipe(ialu_cconly_reg_imm_zero); 1.7975 +%} 1.7976 + 1.7977 +instruct compL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2 ) %{ 1.7978 + match(Set xcc (CmpL op1 op2)); 1.7979 + effect( DEF xcc, USE op1, USE op2 ); 1.7980 + 1.7981 + size(4); 1.7982 + format %{ "CMP $op1,$op2\t\t! long" %} 1.7983 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.7984 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.7985 + ins_pipe(ialu_cconly_reg_reg); 1.7986 +%} 1.7987 + 1.7988 +instruct compL_reg_con(flagsRegL xcc, iRegL op1, immL13 con) %{ 1.7989 + match(Set xcc (CmpL op1 con)); 1.7990 + effect( DEF xcc, USE op1, USE con ); 1.7991 + 1.7992 + size(4); 1.7993 + format %{ "CMP $op1,$con\t\t! long" %} 1.7994 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.7995 + ins_encode( form3_rs1_simm13_rd( op1, con, R_G0 ) ); 1.7996 + ins_pipe(ialu_cconly_reg_reg); 1.7997 +%} 1.7998 + 1.7999 +instruct testL_reg_reg(flagsRegL xcc, iRegL op1, iRegL op2, immL0 zero) %{ 1.8000 + match(Set xcc (CmpL (AndL op1 op2) zero)); 1.8001 + effect( DEF xcc, USE op1, USE op2 ); 1.8002 + 1.8003 + size(4); 1.8004 + format %{ "BTST $op1,$op2\t\t! long" %} 1.8005 + opcode(Assembler::andcc_op3, Assembler::arith_op); 1.8006 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.8007 + ins_pipe(ialu_cconly_reg_reg); 1.8008 +%} 1.8009 + 1.8010 +// useful for checking the alignment of a pointer: 1.8011 +instruct testL_reg_con(flagsRegL xcc, iRegL op1, immL13 con, immL0 zero) %{ 1.8012 + match(Set xcc (CmpL (AndL op1 con) zero)); 1.8013 + effect( DEF xcc, USE op1, USE con ); 1.8014 + 1.8015 + size(4); 1.8016 + format %{ "BTST $op1,$con\t\t! long" %} 1.8017 + opcode(Assembler::andcc_op3, Assembler::arith_op); 1.8018 + ins_encode( form3_rs1_simm13_rd( op1, con, R_G0 ) ); 1.8019 + ins_pipe(ialu_cconly_reg_reg); 1.8020 +%} 1.8021 + 1.8022 +instruct compU_iReg_imm13(flagsRegU icc, iRegI op1, immU13 op2 ) %{ 1.8023 + match(Set icc (CmpU op1 op2)); 1.8024 + 1.8025 + size(4); 1.8026 + format %{ "CMP $op1,$op2\t! unsigned" %} 1.8027 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.8028 + ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); 1.8029 + ins_pipe(ialu_cconly_reg_imm); 1.8030 +%} 1.8031 + 1.8032 +// Compare Pointers 1.8033 +instruct compP_iRegP(flagsRegP pcc, iRegP op1, iRegP op2 ) %{ 1.8034 + match(Set pcc (CmpP op1 op2)); 1.8035 + 1.8036 + size(4); 1.8037 + format %{ "CMP $op1,$op2\t! ptr" %} 1.8038 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.8039 + ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) ); 1.8040 + ins_pipe(ialu_cconly_reg_reg); 1.8041 +%} 1.8042 + 1.8043 +instruct compP_iRegP_imm13(flagsRegP pcc, iRegP op1, immP13 op2 ) %{ 1.8044 + match(Set pcc (CmpP op1 op2)); 1.8045 + 1.8046 + size(4); 1.8047 + format %{ "CMP $op1,$op2\t! ptr" %} 1.8048 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.8049 + ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); 1.8050 + ins_pipe(ialu_cconly_reg_imm); 1.8051 +%} 1.8052 + 1.8053 +//----------Max and Min-------------------------------------------------------- 1.8054 +// Min Instructions 1.8055 +// Conditional move for min 1.8056 +instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{ 1.8057 + effect( USE_DEF op2, USE op1, USE icc ); 1.8058 + 1.8059 + size(4); 1.8060 + format %{ "MOVlt icc,$op1,$op2\t! min" %} 1.8061 + opcode(Assembler::less); 1.8062 + ins_encode( enc_cmov_reg_minmax(op2,op1) ); 1.8063 + ins_pipe(ialu_reg_flags); 1.8064 +%} 1.8065 + 1.8066 +// Min Register with Register. 1.8067 +instruct minI_eReg(iRegI op1, iRegI op2) %{ 1.8068 + match(Set op2 (MinI op1 op2)); 1.8069 + ins_cost(DEFAULT_COST*2); 1.8070 + expand %{ 1.8071 + flagsReg icc; 1.8072 + compI_iReg(icc,op1,op2); 1.8073 + cmovI_reg_lt(op2,op1,icc); 1.8074 + %} 1.8075 +%} 1.8076 + 1.8077 +// Max Instructions 1.8078 +// Conditional move for max 1.8079 +instruct cmovI_reg_gt( iRegI op2, iRegI op1, flagsReg icc ) %{ 1.8080 + effect( USE_DEF op2, USE op1, USE icc ); 1.8081 + format %{ "MOVgt icc,$op1,$op2\t! max" %} 1.8082 + opcode(Assembler::greater); 1.8083 + ins_encode( enc_cmov_reg_minmax(op2,op1) ); 1.8084 + ins_pipe(ialu_reg_flags); 1.8085 +%} 1.8086 + 1.8087 +// Max Register with Register 1.8088 +instruct maxI_eReg(iRegI op1, iRegI op2) %{ 1.8089 + match(Set op2 (MaxI op1 op2)); 1.8090 + ins_cost(DEFAULT_COST*2); 1.8091 + expand %{ 1.8092 + flagsReg icc; 1.8093 + compI_iReg(icc,op1,op2); 1.8094 + cmovI_reg_gt(op2,op1,icc); 1.8095 + %} 1.8096 +%} 1.8097 + 1.8098 + 1.8099 +//----------Float Compares---------------------------------------------------- 1.8100 +// Compare floating, generate condition code 1.8101 +instruct cmpF_cc(flagsRegF fcc, regF src1, regF src2) %{ 1.8102 + match(Set fcc (CmpF src1 src2)); 1.8103 + 1.8104 + size(4); 1.8105 + format %{ "FCMPs $fcc,$src1,$src2" %} 1.8106 + opcode(Assembler::fpop2_op3, Assembler::arith_op, Assembler::fcmps_opf); 1.8107 + ins_encode( form3_opf_rs1F_rs2F_fcc( src1, src2, fcc ) ); 1.8108 + ins_pipe(faddF_fcc_reg_reg_zero); 1.8109 +%} 1.8110 + 1.8111 +instruct cmpD_cc(flagsRegF fcc, regD src1, regD src2) %{ 1.8112 + match(Set fcc (CmpD src1 src2)); 1.8113 + 1.8114 + size(4); 1.8115 + format %{ "FCMPd $fcc,$src1,$src2" %} 1.8116 + opcode(Assembler::fpop2_op3, Assembler::arith_op, Assembler::fcmpd_opf); 1.8117 + ins_encode( form3_opf_rs1D_rs2D_fcc( src1, src2, fcc ) ); 1.8118 + ins_pipe(faddD_fcc_reg_reg_zero); 1.8119 +%} 1.8120 + 1.8121 + 1.8122 +// Compare floating, generate -1,0,1 1.8123 +instruct cmpF_reg(iRegI dst, regF src1, regF src2, flagsRegF0 fcc0) %{ 1.8124 + match(Set dst (CmpF3 src1 src2)); 1.8125 + effect(KILL fcc0); 1.8126 + ins_cost(DEFAULT_COST*3+BRANCH_COST*3); 1.8127 + format %{ "fcmpl $dst,$src1,$src2" %} 1.8128 + // Primary = float 1.8129 + opcode( true ); 1.8130 + ins_encode( floating_cmp( dst, src1, src2 ) ); 1.8131 + ins_pipe( floating_cmp ); 1.8132 +%} 1.8133 + 1.8134 +instruct cmpD_reg(iRegI dst, regD src1, regD src2, flagsRegF0 fcc0) %{ 1.8135 + match(Set dst (CmpD3 src1 src2)); 1.8136 + effect(KILL fcc0); 1.8137 + ins_cost(DEFAULT_COST*3+BRANCH_COST*3); 1.8138 + format %{ "dcmpl $dst,$src1,$src2" %} 1.8139 + // Primary = double (not float) 1.8140 + opcode( false ); 1.8141 + ins_encode( floating_cmp( dst, src1, src2 ) ); 1.8142 + ins_pipe( floating_cmp ); 1.8143 +%} 1.8144 + 1.8145 +//----------Branches--------------------------------------------------------- 1.8146 +// Jump 1.8147 +// (compare 'operand indIndex' and 'instruct addP_reg_reg' above) 1.8148 +instruct jumpXtnd(iRegX switch_val, o7RegI table) %{ 1.8149 + match(Jump switch_val); 1.8150 + 1.8151 + ins_cost(350); 1.8152 + 1.8153 + format %{ "SETHI [hi(table_base)],O7\n\t" 1.8154 + "ADD O7, lo(table_base), O7\n\t" 1.8155 + "LD [O7+$switch_val], O7\n\t" 1.8156 + "JUMP O7" 1.8157 + %} 1.8158 + ins_encode( jump_enc( switch_val, table) ); 1.8159 + ins_pc_relative(1); 1.8160 + ins_pipe(ialu_reg_reg); 1.8161 +%} 1.8162 + 1.8163 +// Direct Branch. Use V8 version with longer range. 1.8164 +instruct branch(label labl) %{ 1.8165 + match(Goto); 1.8166 + effect(USE labl); 1.8167 + 1.8168 + size(8); 1.8169 + ins_cost(BRANCH_COST); 1.8170 + format %{ "BA $labl" %} 1.8171 + // Prim = bits 24-22, Secnd = bits 31-30, Tert = cond 1.8172 + opcode(Assembler::br_op2, Assembler::branch_op, Assembler::always); 1.8173 + ins_encode( enc_ba( labl ) ); 1.8174 + ins_pc_relative(1); 1.8175 + ins_pipe(br); 1.8176 +%} 1.8177 + 1.8178 +// Conditional Direct Branch 1.8179 +instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ 1.8180 + match(If cmp icc); 1.8181 + effect(USE labl); 1.8182 + 1.8183 + size(8); 1.8184 + ins_cost(BRANCH_COST); 1.8185 + format %{ "BP$cmp $icc,$labl" %} 1.8186 + // Prim = bits 24-22, Secnd = bits 31-30 1.8187 + ins_encode( enc_bp( labl, cmp, icc ) ); 1.8188 + ins_pc_relative(1); 1.8189 + ins_pipe(br_cc); 1.8190 +%} 1.8191 + 1.8192 +// Branch-on-register tests all 64 bits. We assume that values 1.8193 +// in 64-bit registers always remains zero or sign extended 1.8194 +// unless our code munges the high bits. Interrupts can chop 1.8195 +// the high order bits to zero or sign at any time. 1.8196 +instruct branchCon_regI(cmpOp_reg cmp, iRegI op1, immI0 zero, label labl) %{ 1.8197 + match(If cmp (CmpI op1 zero)); 1.8198 + predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); 1.8199 + effect(USE labl); 1.8200 + 1.8201 + size(8); 1.8202 + ins_cost(BRANCH_COST); 1.8203 + format %{ "BR$cmp $op1,$labl" %} 1.8204 + ins_encode( enc_bpr( labl, cmp, op1 ) ); 1.8205 + ins_pc_relative(1); 1.8206 + ins_pipe(br_reg); 1.8207 +%} 1.8208 + 1.8209 +instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{ 1.8210 + match(If cmp (CmpP op1 null)); 1.8211 + predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); 1.8212 + effect(USE labl); 1.8213 + 1.8214 + size(8); 1.8215 + ins_cost(BRANCH_COST); 1.8216 + format %{ "BR$cmp $op1,$labl" %} 1.8217 + ins_encode( enc_bpr( labl, cmp, op1 ) ); 1.8218 + ins_pc_relative(1); 1.8219 + ins_pipe(br_reg); 1.8220 +%} 1.8221 + 1.8222 +instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{ 1.8223 + match(If cmp (CmpL op1 zero)); 1.8224 + predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf)); 1.8225 + effect(USE labl); 1.8226 + 1.8227 + size(8); 1.8228 + ins_cost(BRANCH_COST); 1.8229 + format %{ "BR$cmp $op1,$labl" %} 1.8230 + ins_encode( enc_bpr( labl, cmp, op1 ) ); 1.8231 + ins_pc_relative(1); 1.8232 + ins_pipe(br_reg); 1.8233 +%} 1.8234 + 1.8235 +instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ 1.8236 + match(If cmp icc); 1.8237 + effect(USE labl); 1.8238 + 1.8239 + format %{ "BP$cmp $icc,$labl" %} 1.8240 + // Prim = bits 24-22, Secnd = bits 31-30 1.8241 + ins_encode( enc_bp( labl, cmp, icc ) ); 1.8242 + ins_pc_relative(1); 1.8243 + ins_pipe(br_cc); 1.8244 +%} 1.8245 + 1.8246 +instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ 1.8247 + match(If cmp pcc); 1.8248 + effect(USE labl); 1.8249 + 1.8250 + size(8); 1.8251 + ins_cost(BRANCH_COST); 1.8252 + format %{ "BP$cmp $pcc,$labl" %} 1.8253 + // Prim = bits 24-22, Secnd = bits 31-30 1.8254 + ins_encode( enc_bpx( labl, cmp, pcc ) ); 1.8255 + ins_pc_relative(1); 1.8256 + ins_pipe(br_cc); 1.8257 +%} 1.8258 + 1.8259 +instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ 1.8260 + match(If cmp fcc); 1.8261 + effect(USE labl); 1.8262 + 1.8263 + size(8); 1.8264 + ins_cost(BRANCH_COST); 1.8265 + format %{ "FBP$cmp $fcc,$labl" %} 1.8266 + // Prim = bits 24-22, Secnd = bits 31-30 1.8267 + ins_encode( enc_fbp( labl, cmp, fcc ) ); 1.8268 + ins_pc_relative(1); 1.8269 + ins_pipe(br_fcc); 1.8270 +%} 1.8271 + 1.8272 +instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ 1.8273 + match(CountedLoopEnd cmp icc); 1.8274 + effect(USE labl); 1.8275 + 1.8276 + size(8); 1.8277 + ins_cost(BRANCH_COST); 1.8278 + format %{ "BP$cmp $icc,$labl\t! Loop end" %} 1.8279 + // Prim = bits 24-22, Secnd = bits 31-30 1.8280 + ins_encode( enc_bp( labl, cmp, icc ) ); 1.8281 + ins_pc_relative(1); 1.8282 + ins_pipe(br_cc); 1.8283 +%} 1.8284 + 1.8285 +instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ 1.8286 + match(CountedLoopEnd cmp icc); 1.8287 + effect(USE labl); 1.8288 + 1.8289 + size(8); 1.8290 + ins_cost(BRANCH_COST); 1.8291 + format %{ "BP$cmp $icc,$labl\t! Loop end" %} 1.8292 + // Prim = bits 24-22, Secnd = bits 31-30 1.8293 + ins_encode( enc_bp( labl, cmp, icc ) ); 1.8294 + ins_pc_relative(1); 1.8295 + ins_pipe(br_cc); 1.8296 +%} 1.8297 + 1.8298 +// ============================================================================ 1.8299 +// Long Compare 1.8300 +// 1.8301 +// Currently we hold longs in 2 registers. Comparing such values efficiently 1.8302 +// is tricky. The flavor of compare used depends on whether we are testing 1.8303 +// for LT, LE, or EQ. For a simple LT test we can check just the sign bit. 1.8304 +// The GE test is the negated LT test. The LE test can be had by commuting 1.8305 +// the operands (yielding a GE test) and then negating; negate again for the 1.8306 +// GT test. The EQ test is done by ORcc'ing the high and low halves, and the 1.8307 +// NE test is negated from that. 1.8308 + 1.8309 +// Due to a shortcoming in the ADLC, it mixes up expressions like: 1.8310 +// (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)). Note the 1.8311 +// difference between 'Y' and '0L'. The tree-matches for the CmpI sections 1.8312 +// are collapsed internally in the ADLC's dfa-gen code. The match for 1.8313 +// (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the 1.8314 +// foo match ends up with the wrong leaf. One fix is to not match both 1.8315 +// reg-reg and reg-zero forms of long-compare. This is unfortunate because 1.8316 +// both forms beat the trinary form of long-compare and both are very useful 1.8317 +// on Intel which has so few registers. 1.8318 + 1.8319 +instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{ 1.8320 + match(If cmp xcc); 1.8321 + effect(USE labl); 1.8322 + 1.8323 + size(8); 1.8324 + ins_cost(BRANCH_COST); 1.8325 + format %{ "BP$cmp $xcc,$labl" %} 1.8326 + // Prim = bits 24-22, Secnd = bits 31-30 1.8327 + ins_encode( enc_bpl( labl, cmp, xcc ) ); 1.8328 + ins_pc_relative(1); 1.8329 + ins_pipe(br_cc); 1.8330 +%} 1.8331 + 1.8332 +// Manifest a CmpL3 result in an integer register. Very painful. 1.8333 +// This is the test to avoid. 1.8334 +instruct cmpL3_reg_reg(iRegI dst, iRegL src1, iRegL src2, flagsReg ccr ) %{ 1.8335 + match(Set dst (CmpL3 src1 src2) ); 1.8336 + effect( KILL ccr ); 1.8337 + ins_cost(6*DEFAULT_COST); 1.8338 + size(24); 1.8339 + format %{ "CMP $src1,$src2\t\t! long\n" 1.8340 + "\tBLT,a,pn done\n" 1.8341 + "\tMOV -1,$dst\t! delay slot\n" 1.8342 + "\tBGT,a,pn done\n" 1.8343 + "\tMOV 1,$dst\t! delay slot\n" 1.8344 + "\tCLR $dst\n" 1.8345 + "done:" %} 1.8346 + ins_encode( cmpl_flag(src1,src2,dst) ); 1.8347 + ins_pipe(cmpL_reg); 1.8348 +%} 1.8349 + 1.8350 +// Conditional move 1.8351 +instruct cmovLL_reg(cmpOp cmp, flagsRegL xcc, iRegL dst, iRegL src) %{ 1.8352 + match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); 1.8353 + ins_cost(150); 1.8354 + format %{ "MOV$cmp $xcc,$src,$dst\t! long" %} 1.8355 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); 1.8356 + ins_pipe(ialu_reg); 1.8357 +%} 1.8358 + 1.8359 +instruct cmovLL_imm(cmpOp cmp, flagsRegL xcc, iRegL dst, immL0 src) %{ 1.8360 + match(Set dst (CMoveL (Binary cmp xcc) (Binary dst src))); 1.8361 + ins_cost(140); 1.8362 + format %{ "MOV$cmp $xcc,$src,$dst\t! long" %} 1.8363 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); 1.8364 + ins_pipe(ialu_imm); 1.8365 +%} 1.8366 + 1.8367 +instruct cmovIL_reg(cmpOp cmp, flagsRegL xcc, iRegI dst, iRegI src) %{ 1.8368 + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); 1.8369 + ins_cost(150); 1.8370 + format %{ "MOV$cmp $xcc,$src,$dst" %} 1.8371 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); 1.8372 + ins_pipe(ialu_reg); 1.8373 +%} 1.8374 + 1.8375 +instruct cmovIL_imm(cmpOp cmp, flagsRegL xcc, iRegI dst, immI11 src) %{ 1.8376 + match(Set dst (CMoveI (Binary cmp xcc) (Binary dst src))); 1.8377 + ins_cost(140); 1.8378 + format %{ "MOV$cmp $xcc,$src,$dst" %} 1.8379 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); 1.8380 + ins_pipe(ialu_imm); 1.8381 +%} 1.8382 + 1.8383 +instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{ 1.8384 + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); 1.8385 + ins_cost(150); 1.8386 + format %{ "MOV$cmp $xcc,$src,$dst" %} 1.8387 + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) ); 1.8388 + ins_pipe(ialu_reg); 1.8389 +%} 1.8390 + 1.8391 +instruct cmovPL_imm(cmpOp cmp, flagsRegL xcc, iRegP dst, immP0 src) %{ 1.8392 + match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); 1.8393 + ins_cost(140); 1.8394 + format %{ "MOV$cmp $xcc,$src,$dst" %} 1.8395 + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) ); 1.8396 + ins_pipe(ialu_imm); 1.8397 +%} 1.8398 + 1.8399 +instruct cmovFL_reg(cmpOp cmp, flagsRegL xcc, regF dst, regF src) %{ 1.8400 + match(Set dst (CMoveF (Binary cmp xcc) (Binary dst src))); 1.8401 + ins_cost(150); 1.8402 + opcode(0x101); 1.8403 + format %{ "FMOVS$cmp $xcc,$src,$dst" %} 1.8404 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::xcc)) ); 1.8405 + ins_pipe(int_conditional_float_move); 1.8406 +%} 1.8407 + 1.8408 +instruct cmovDL_reg(cmpOp cmp, flagsRegL xcc, regD dst, regD src) %{ 1.8409 + match(Set dst (CMoveD (Binary cmp xcc) (Binary dst src))); 1.8410 + ins_cost(150); 1.8411 + opcode(0x102); 1.8412 + format %{ "FMOVD$cmp $xcc,$src,$dst" %} 1.8413 + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::xcc)) ); 1.8414 + ins_pipe(int_conditional_float_move); 1.8415 +%} 1.8416 + 1.8417 +// ============================================================================ 1.8418 +// Safepoint Instruction 1.8419 +instruct safePoint_poll(iRegP poll) %{ 1.8420 + match(SafePoint poll); 1.8421 + effect(USE poll); 1.8422 + 1.8423 + size(4); 1.8424 +#ifdef _LP64 1.8425 + format %{ "LDX [$poll],R_G0\t! Safepoint: poll for GC" %} 1.8426 +#else 1.8427 + format %{ "LDUW [$poll],R_G0\t! Safepoint: poll for GC" %} 1.8428 +#endif 1.8429 + ins_encode %{ 1.8430 + __ relocate(relocInfo::poll_type); 1.8431 + __ ld_ptr($poll$$Register, 0, G0); 1.8432 + %} 1.8433 + ins_pipe(loadPollP); 1.8434 +%} 1.8435 + 1.8436 +// ============================================================================ 1.8437 +// Call Instructions 1.8438 +// Call Java Static Instruction 1.8439 +instruct CallStaticJavaDirect( method meth ) %{ 1.8440 + match(CallStaticJava); 1.8441 + effect(USE meth); 1.8442 + 1.8443 + size(8); 1.8444 + ins_cost(CALL_COST); 1.8445 + format %{ "CALL,static ; NOP ==> " %} 1.8446 + ins_encode( Java_Static_Call( meth ), call_epilog ); 1.8447 + ins_pc_relative(1); 1.8448 + ins_pipe(simple_call); 1.8449 +%} 1.8450 + 1.8451 +// Call Java Dynamic Instruction 1.8452 +instruct CallDynamicJavaDirect( method meth ) %{ 1.8453 + match(CallDynamicJava); 1.8454 + effect(USE meth); 1.8455 + 1.8456 + ins_cost(CALL_COST); 1.8457 + format %{ "SET (empty),R_G5\n\t" 1.8458 + "CALL,dynamic ; NOP ==> " %} 1.8459 + ins_encode( Java_Dynamic_Call( meth ), call_epilog ); 1.8460 + ins_pc_relative(1); 1.8461 + ins_pipe(call); 1.8462 +%} 1.8463 + 1.8464 +// Call Runtime Instruction 1.8465 +instruct CallRuntimeDirect(method meth, l7RegP l7) %{ 1.8466 + match(CallRuntime); 1.8467 + effect(USE meth, KILL l7); 1.8468 + ins_cost(CALL_COST); 1.8469 + format %{ "CALL,runtime" %} 1.8470 + ins_encode( Java_To_Runtime( meth ), 1.8471 + call_epilog, adjust_long_from_native_call ); 1.8472 + ins_pc_relative(1); 1.8473 + ins_pipe(simple_call); 1.8474 +%} 1.8475 + 1.8476 +// Call runtime without safepoint - same as CallRuntime 1.8477 +instruct CallLeafDirect(method meth, l7RegP l7) %{ 1.8478 + match(CallLeaf); 1.8479 + effect(USE meth, KILL l7); 1.8480 + ins_cost(CALL_COST); 1.8481 + format %{ "CALL,runtime leaf" %} 1.8482 + ins_encode( Java_To_Runtime( meth ), 1.8483 + call_epilog, 1.8484 + adjust_long_from_native_call ); 1.8485 + ins_pc_relative(1); 1.8486 + ins_pipe(simple_call); 1.8487 +%} 1.8488 + 1.8489 +// Call runtime without safepoint - same as CallLeaf 1.8490 +instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{ 1.8491 + match(CallLeafNoFP); 1.8492 + effect(USE meth, KILL l7); 1.8493 + ins_cost(CALL_COST); 1.8494 + format %{ "CALL,runtime leaf nofp" %} 1.8495 + ins_encode( Java_To_Runtime( meth ), 1.8496 + call_epilog, 1.8497 + adjust_long_from_native_call ); 1.8498 + ins_pc_relative(1); 1.8499 + ins_pipe(simple_call); 1.8500 +%} 1.8501 + 1.8502 +// Tail Call; Jump from runtime stub to Java code. 1.8503 +// Also known as an 'interprocedural jump'. 1.8504 +// Target of jump will eventually return to caller. 1.8505 +// TailJump below removes the return address. 1.8506 +instruct TailCalljmpInd(g3RegP jump_target, inline_cache_regP method_oop) %{ 1.8507 + match(TailCall jump_target method_oop ); 1.8508 + 1.8509 + ins_cost(CALL_COST); 1.8510 + format %{ "Jmp $jump_target ; NOP \t! $method_oop holds method oop" %} 1.8511 + ins_encode(form_jmpl(jump_target)); 1.8512 + ins_pipe(tail_call); 1.8513 +%} 1.8514 + 1.8515 + 1.8516 +// Return Instruction 1.8517 +instruct Ret() %{ 1.8518 + match(Return); 1.8519 + 1.8520 + // The epilogue node did the ret already. 1.8521 + size(0); 1.8522 + format %{ "! return" %} 1.8523 + ins_encode(); 1.8524 + ins_pipe(empty); 1.8525 +%} 1.8526 + 1.8527 + 1.8528 +// Tail Jump; remove the return address; jump to target. 1.8529 +// TailCall above leaves the return address around. 1.8530 +// TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 1.8531 +// ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 1.8532 +// "restore" before this instruction (in Epilogue), we need to materialize it 1.8533 +// in %i0. 1.8534 +instruct tailjmpInd(g1RegP jump_target, i0RegP ex_oop) %{ 1.8535 + match( TailJump jump_target ex_oop ); 1.8536 + ins_cost(CALL_COST); 1.8537 + format %{ "! discard R_O7\n\t" 1.8538 + "Jmp $jump_target ; ADD O7,8,O1 \t! $ex_oop holds exc. oop" %} 1.8539 + ins_encode(form_jmpl_set_exception_pc(jump_target)); 1.8540 + // opcode(Assembler::jmpl_op3, Assembler::arith_op); 1.8541 + // The hack duplicates the exception oop into G3, so that CreateEx can use it there. 1.8542 + // ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() ); 1.8543 + ins_pipe(tail_call); 1.8544 +%} 1.8545 + 1.8546 +// Create exception oop: created by stack-crawling runtime code. 1.8547 +// Created exception is now available to this handler, and is setup 1.8548 +// just prior to jumping to this handler. No code emitted. 1.8549 +instruct CreateException( o0RegP ex_oop ) 1.8550 +%{ 1.8551 + match(Set ex_oop (CreateEx)); 1.8552 + ins_cost(0); 1.8553 + 1.8554 + size(0); 1.8555 + // use the following format syntax 1.8556 + format %{ "! exception oop is in R_O0; no code emitted" %} 1.8557 + ins_encode(); 1.8558 + ins_pipe(empty); 1.8559 +%} 1.8560 + 1.8561 + 1.8562 +// Rethrow exception: 1.8563 +// The exception oop will come in the first argument position. 1.8564 +// Then JUMP (not call) to the rethrow stub code. 1.8565 +instruct RethrowException() 1.8566 +%{ 1.8567 + match(Rethrow); 1.8568 + ins_cost(CALL_COST); 1.8569 + 1.8570 + // use the following format syntax 1.8571 + format %{ "Jmp rethrow_stub" %} 1.8572 + ins_encode(enc_rethrow); 1.8573 + ins_pipe(tail_call); 1.8574 +%} 1.8575 + 1.8576 + 1.8577 +// Die now 1.8578 +instruct ShouldNotReachHere( ) 1.8579 +%{ 1.8580 + match(Halt); 1.8581 + ins_cost(CALL_COST); 1.8582 + 1.8583 + size(4); 1.8584 + // Use the following format syntax 1.8585 + format %{ "ILLTRAP ; ShouldNotReachHere" %} 1.8586 + ins_encode( form2_illtrap() ); 1.8587 + ins_pipe(tail_call); 1.8588 +%} 1.8589 + 1.8590 +// ============================================================================ 1.8591 +// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 1.8592 +// array for an instance of the superklass. Set a hidden internal cache on a 1.8593 +// hit (cache is checked with exposed code in gen_subtype_check()). Return 1.8594 +// not zero for a miss or zero for a hit. The encoding ALSO sets flags. 1.8595 +instruct partialSubtypeCheck( o0RegP index, o1RegP sub, o2RegP super, flagsRegP pcc, o7RegP o7 ) %{ 1.8596 + match(Set index (PartialSubtypeCheck sub super)); 1.8597 + effect( KILL pcc, KILL o7 ); 1.8598 + ins_cost(DEFAULT_COST*10); 1.8599 + format %{ "CALL PartialSubtypeCheck\n\tNOP" %} 1.8600 + ins_encode( enc_PartialSubtypeCheck() ); 1.8601 + ins_pipe(partial_subtype_check_pipe); 1.8602 +%} 1.8603 + 1.8604 +instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, immP0 zero, o0RegP idx, o7RegP o7 ) %{ 1.8605 + match(Set pcc (CmpP (PartialSubtypeCheck sub super) zero)); 1.8606 + effect( KILL idx, KILL o7 ); 1.8607 + ins_cost(DEFAULT_COST*10); 1.8608 + format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} 1.8609 + ins_encode( enc_PartialSubtypeCheck() ); 1.8610 + ins_pipe(partial_subtype_check_pipe); 1.8611 +%} 1.8612 + 1.8613 +// ============================================================================ 1.8614 +// inlined locking and unlocking 1.8615 + 1.8616 +instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ 1.8617 + match(Set pcc (FastLock object box)); 1.8618 + 1.8619 + effect(KILL scratch, TEMP scratch2); 1.8620 + ins_cost(100); 1.8621 + 1.8622 + size(4*112); // conservative overestimation ... 1.8623 + format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} 1.8624 + ins_encode( Fast_Lock(object, box, scratch, scratch2) ); 1.8625 + ins_pipe(long_memory_op); 1.8626 +%} 1.8627 + 1.8628 + 1.8629 +instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ 1.8630 + match(Set pcc (FastUnlock object box)); 1.8631 + effect(KILL scratch, TEMP scratch2); 1.8632 + ins_cost(100); 1.8633 + 1.8634 + size(4*120); // conservative overestimation ... 1.8635 + format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} 1.8636 + ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); 1.8637 + ins_pipe(long_memory_op); 1.8638 +%} 1.8639 + 1.8640 +// Count and Base registers are fixed because the allocator cannot 1.8641 +// kill unknown registers. The encodings are generic. 1.8642 +instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{ 1.8643 + match(Set dummy (ClearArray cnt base)); 1.8644 + effect(TEMP temp, KILL ccr); 1.8645 + ins_cost(300); 1.8646 + format %{ "MOV $cnt,$temp\n" 1.8647 + "loop: SUBcc $temp,8,$temp\t! Count down a dword of bytes\n" 1.8648 + " BRge loop\t\t! Clearing loop\n" 1.8649 + " STX G0,[$base+$temp]\t! delay slot" %} 1.8650 + ins_encode( enc_Clear_Array(cnt, base, temp) ); 1.8651 + ins_pipe(long_memory_op); 1.8652 +%} 1.8653 + 1.8654 +instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{ 1.8655 + match(Set result (StrComp str1 str2)); 1.8656 + effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr); 1.8657 + ins_cost(300); 1.8658 + format %{ "String Compare $str1,$str2 -> $result" %} 1.8659 + ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) ); 1.8660 + ins_pipe(long_memory_op); 1.8661 +%} 1.8662 + 1.8663 +// ============================================================================ 1.8664 +//------------Bytes reverse-------------------------------------------------- 1.8665 + 1.8666 +instruct bytes_reverse_int(iRegI dst, stackSlotI src) %{ 1.8667 + match(Set dst (ReverseBytesI src)); 1.8668 + effect(DEF dst, USE src); 1.8669 + 1.8670 + // Op cost is artificially doubled to make sure that load or store 1.8671 + // instructions are preferred over this one which requires a spill 1.8672 + // onto a stack slot. 1.8673 + ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); 1.8674 + size(8); 1.8675 + format %{ "LDUWA $src, $dst\t!asi=primary_little" %} 1.8676 + opcode(Assembler::lduwa_op3); 1.8677 + ins_encode( form3_mem_reg_little(src, dst) ); 1.8678 + ins_pipe( iload_mem ); 1.8679 +%} 1.8680 + 1.8681 +instruct bytes_reverse_long(iRegL dst, stackSlotL src) %{ 1.8682 + match(Set dst (ReverseBytesL src)); 1.8683 + effect(DEF dst, USE src); 1.8684 + 1.8685 + // Op cost is artificially doubled to make sure that load or store 1.8686 + // instructions are preferred over this one which requires a spill 1.8687 + // onto a stack slot. 1.8688 + ins_cost(2*DEFAULT_COST + MEMORY_REF_COST); 1.8689 + size(8); 1.8690 + format %{ "LDXA $src, $dst\t!asi=primary_little" %} 1.8691 + 1.8692 + opcode(Assembler::ldxa_op3); 1.8693 + ins_encode( form3_mem_reg_little(src, dst) ); 1.8694 + ins_pipe( iload_mem ); 1.8695 +%} 1.8696 + 1.8697 +// Load Integer reversed byte order 1.8698 +instruct loadI_reversed(iRegI dst, memory src) %{ 1.8699 + match(Set dst (ReverseBytesI (LoadI src))); 1.8700 + 1.8701 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.8702 + size(8); 1.8703 + format %{ "LDUWA $src, $dst\t!asi=primary_little" %} 1.8704 + 1.8705 + opcode(Assembler::lduwa_op3); 1.8706 + ins_encode( form3_mem_reg_little( src, dst) ); 1.8707 + ins_pipe(iload_mem); 1.8708 +%} 1.8709 + 1.8710 +// Load Long - aligned and reversed 1.8711 +instruct loadL_reversed(iRegL dst, memory src) %{ 1.8712 + match(Set dst (ReverseBytesL (LoadL src))); 1.8713 + 1.8714 + ins_cost(DEFAULT_COST + MEMORY_REF_COST); 1.8715 + size(8); 1.8716 + format %{ "LDXA $src, $dst\t!asi=primary_little" %} 1.8717 + 1.8718 + opcode(Assembler::ldxa_op3); 1.8719 + ins_encode( form3_mem_reg_little( src, dst ) ); 1.8720 + ins_pipe(iload_mem); 1.8721 +%} 1.8722 + 1.8723 +// Store Integer reversed byte order 1.8724 +instruct storeI_reversed(memory dst, iRegI src) %{ 1.8725 + match(Set dst (StoreI dst (ReverseBytesI src))); 1.8726 + 1.8727 + ins_cost(MEMORY_REF_COST); 1.8728 + size(8); 1.8729 + format %{ "STWA $src, $dst\t!asi=primary_little" %} 1.8730 + 1.8731 + opcode(Assembler::stwa_op3); 1.8732 + ins_encode( form3_mem_reg_little( dst, src) ); 1.8733 + ins_pipe(istore_mem_reg); 1.8734 +%} 1.8735 + 1.8736 +// Store Long reversed byte order 1.8737 +instruct storeL_reversed(memory dst, iRegL src) %{ 1.8738 + match(Set dst (StoreL dst (ReverseBytesL src))); 1.8739 + 1.8740 + ins_cost(MEMORY_REF_COST); 1.8741 + size(8); 1.8742 + format %{ "STXA $src, $dst\t!asi=primary_little" %} 1.8743 + 1.8744 + opcode(Assembler::stxa_op3); 1.8745 + ins_encode( form3_mem_reg_little( dst, src) ); 1.8746 + ins_pipe(istore_mem_reg); 1.8747 +%} 1.8748 + 1.8749 +//----------PEEPHOLE RULES----------------------------------------------------- 1.8750 +// These must follow all instruction definitions as they use the names 1.8751 +// defined in the instructions definitions. 1.8752 +// 1.8753 +// peepmatch ( root_instr_name [preceeding_instruction]* ); 1.8754 +// 1.8755 +// peepconstraint %{ 1.8756 +// (instruction_number.operand_name relational_op instruction_number.operand_name 1.8757 +// [, ...] ); 1.8758 +// // instruction numbers are zero-based using left to right order in peepmatch 1.8759 +// 1.8760 +// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 1.8761 +// // provide an instruction_number.operand_name for each operand that appears 1.8762 +// // in the replacement instruction's match rule 1.8763 +// 1.8764 +// ---------VM FLAGS--------------------------------------------------------- 1.8765 +// 1.8766 +// All peephole optimizations can be turned off using -XX:-OptoPeephole 1.8767 +// 1.8768 +// Each peephole rule is given an identifying number starting with zero and 1.8769 +// increasing by one in the order seen by the parser. An individual peephole 1.8770 +// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 1.8771 +// on the command-line. 1.8772 +// 1.8773 +// ---------CURRENT LIMITATIONS---------------------------------------------- 1.8774 +// 1.8775 +// Only match adjacent instructions in same basic block 1.8776 +// Only equality constraints 1.8777 +// Only constraints between operands, not (0.dest_reg == EAX_enc) 1.8778 +// Only one replacement instruction 1.8779 +// 1.8780 +// ---------EXAMPLE---------------------------------------------------------- 1.8781 +// 1.8782 +// // pertinent parts of existing instructions in architecture description 1.8783 +// instruct movI(eRegI dst, eRegI src) %{ 1.8784 +// match(Set dst (CopyI src)); 1.8785 +// %} 1.8786 +// 1.8787 +// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 1.8788 +// match(Set dst (AddI dst src)); 1.8789 +// effect(KILL cr); 1.8790 +// %} 1.8791 +// 1.8792 +// // Change (inc mov) to lea 1.8793 +// peephole %{ 1.8794 +// // increment preceeded by register-register move 1.8795 +// peepmatch ( incI_eReg movI ); 1.8796 +// // require that the destination register of the increment 1.8797 +// // match the destination register of the move 1.8798 +// peepconstraint ( 0.dst == 1.dst ); 1.8799 +// // construct a replacement instruction that sets 1.8800 +// // the destination to ( move's source register + one ) 1.8801 +// peepreplace ( incI_eReg_immI1( 0.dst 1.src 0.src ) ); 1.8802 +// %} 1.8803 +// 1.8804 + 1.8805 +// // Change load of spilled value to only a spill 1.8806 +// instruct storeI(memory mem, eRegI src) %{ 1.8807 +// match(Set mem (StoreI mem src)); 1.8808 +// %} 1.8809 +// 1.8810 +// instruct loadI(eRegI dst, memory mem) %{ 1.8811 +// match(Set dst (LoadI mem)); 1.8812 +// %} 1.8813 +// 1.8814 +// peephole %{ 1.8815 +// peepmatch ( loadI storeI ); 1.8816 +// peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 1.8817 +// peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 1.8818 +// %} 1.8819 + 1.8820 +//----------SMARTSPILL RULES--------------------------------------------------- 1.8821 +// These must follow all instruction definitions as they use the names 1.8822 +// defined in the instructions definitions. 1.8823 +// 1.8824 +// SPARC will probably not have any of these rules due to RISC instruction set. 1.8825 + 1.8826 +//----------PIPELINE----------------------------------------------------------- 1.8827 +// Rules which define the behavior of the target architectures pipeline.