1.1 --- a/src/cpu/sparc/vm/sparc.ad Fri Apr 11 09:56:35 2008 -0400 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Sun Apr 13 17:43:42 2008 -0400 1.3 @@ -544,11 +544,19 @@ 1.4 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 1.5 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); 1.6 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); 1.7 + int klass_load_size; 1.8 + if (UseCompressedOops) { 1.9 + klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass() 1.10 + } else { 1.11 + klass_load_size = 1*BytesPerInstWord; 1.12 + } 1.13 if( Assembler::is_simm13(v_off) ) { 1.14 - return (3*BytesPerInstWord + // ld_ptr, ld_ptr, ld_ptr 1.15 + return klass_load_size + 1.16 + (2*BytesPerInstWord + // ld_ptr, ld_ptr 1.17 NativeCall::instruction_size); // call; delay slot 1.18 } else { 1.19 - return (5*BytesPerInstWord + // ld_ptr, set_hi, set, ld_ptr, ld_ptr 1.20 + return klass_load_size + 1.21 + (4*BytesPerInstWord + // set_hi, set, ld_ptr, ld_ptr 1.22 NativeCall::instruction_size); // call; delay slot 1.23 } 1.24 } 1.25 @@ -1591,7 +1599,13 @@ 1.26 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.27 st->print_cr("\nUEP:"); 1.28 #ifdef _LP64 1.29 - st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); 1.30 + if (UseCompressedOops) { 1.31 + st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass"); 1.32 + st->print_cr("\tSLL R_G5,3,R_G5"); 1.33 + st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5"); 1.34 + } else { 1.35 + st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check"); 1.36 + } 1.37 st->print_cr("\tCMP R_G5,R_G3" ); 1.38 st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2"); 1.39 #else // _LP64 1.40 @@ -1610,7 +1624,7 @@ 1.41 assert( G5_ic_reg != temp_reg, "conflicting registers" ); 1.42 1.43 // Load klass from reciever 1.44 - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg); 1.45 + __ load_klass(O0, temp_reg); 1.46 // Compare against expected klass 1.47 __ cmp(temp_reg, G5_ic_reg); 1.48 // Branch to miss code, checks xcc or icc depending 1.49 @@ -1811,6 +1825,11 @@ 1.50 reg == R_I3H_num || 1.51 reg == R_I4H_num || 1.52 reg == R_I5H_num ) return true; 1.53 + 1.54 + if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) { 1.55 + return true; 1.56 + } 1.57 + 1.58 #else 1.59 // 32-bit builds with longs-in-one-entry pass longs in G1 & G4. 1.60 // Longs cannot be passed in O regs, because O regs become I regs 1.61 @@ -2474,7 +2493,13 @@ 1.62 // get receiver klass (receiver already checked for non-null) 1.63 // If we end up going thru a c2i adapter interpreter expects method in G5 1.64 int off = __ offset(); 1.65 - __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch); 1.66 + __ load_klass(O0, G3_scratch); 1.67 + int klass_load_size; 1.68 + if (UseCompressedOops) { 1.69 + klass_load_size = 3*BytesPerInstWord; 1.70 + } else { 1.71 + klass_load_size = 1*BytesPerInstWord; 1.72 + } 1.73 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); 1.74 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); 1.75 if( __ is_simm13(v_off) ) { 1.76 @@ -2484,7 +2509,8 @@ 1.77 __ Assembler::sethi(v_off & ~0x3ff, G5_method); 1.78 __ or3(G5_method, v_off & 0x3ff, G5_method); 1.79 // ld_ptr, set_hi, set 1.80 - assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)"); 1.81 + assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord, 1.82 + "Unexpected instruction size(s)"); 1.83 __ ld_ptr(G3, G5_method, G5_method); 1.84 } 1.85 // NOTE: for vtable dispatches, the vtable entry will never be null. 1.86 @@ -2860,12 +2886,12 @@ 1.87 int count_offset = java_lang_String:: count_offset_in_bytes(); 1.88 1.89 // load str1 (jchar*) base address into tmp1_reg 1.90 - __ ld_ptr(Address(str1_reg, 0, value_offset), tmp1_reg); 1.91 + __ load_heap_oop(Address(str1_reg, 0, value_offset), tmp1_reg); 1.92 __ ld(Address(str1_reg, 0, offset_offset), result_reg); 1.93 __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg); 1.94 __ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted 1.95 __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg); 1.96 - __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted 1.97 + __ load_heap_oop(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted 1.98 __ add(result_reg, tmp1_reg, tmp1_reg); 1.99 1.100 // load str2 (jchar*) base address into tmp2_reg 1.101 @@ -3016,6 +3042,7 @@ 1.102 MacroAssembler _masm(&cbuf); 1.103 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) ); 1.104 %} 1.105 + 1.106 enc_class enc_repl8b( iRegI src, iRegL dst ) %{ 1.107 MacroAssembler _masm(&cbuf); 1.108 Register src_reg = reg_to_register_object($src$$reg); 1.109 @@ -3189,15 +3216,15 @@ 1.110 c_return_value %{ 1.111 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 1.112 #ifdef _LP64 1.113 - 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.114 - 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.115 - 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.116 - 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.117 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; 1.118 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; 1.119 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; 1.120 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; 1.121 #else // !_LP64 1.122 - 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.123 - static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.124 - 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.125 - static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.126 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; 1.127 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.128 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; 1.129 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num }; 1.130 #endif 1.131 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 1.132 (is_outgoing?lo_out:lo_in)[ideal_reg] ); 1.133 @@ -3207,15 +3234,15 @@ 1.134 return_value %{ 1.135 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 1.136 #ifdef _LP64 1.137 - 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.138 - 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.139 - 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.140 - 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.141 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num }; 1.142 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num}; 1.143 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num }; 1.144 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num}; 1.145 #else // !_LP64 1.146 - 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.147 - static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.148 - 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.149 - static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.150 + static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num }; 1.151 + static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.152 + static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num }; 1.153 + static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num}; 1.154 #endif 1.155 return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 1.156 (is_outgoing?lo_out:lo_in)[ideal_reg] ); 1.157 @@ -3408,6 +3435,27 @@ 1.158 interface(CONST_INTER); 1.159 %} 1.160 1.161 +// Pointer Immediate 1.162 +operand immN() 1.163 +%{ 1.164 + match(ConN); 1.165 + 1.166 + op_cost(10); 1.167 + format %{ %} 1.168 + interface(CONST_INTER); 1.169 +%} 1.170 + 1.171 +// NULL Pointer Immediate 1.172 +operand immN0() 1.173 +%{ 1.174 + predicate(n->get_narrowcon() == 0); 1.175 + match(ConN); 1.176 + 1.177 + op_cost(0); 1.178 + format %{ %} 1.179 + interface(CONST_INTER); 1.180 +%} 1.181 + 1.182 operand immL() %{ 1.183 match(ConL); 1.184 op_cost(40); 1.185 @@ -3672,6 +3720,14 @@ 1.186 interface(REG_INTER); 1.187 %} 1.188 1.189 +operand iRegN() %{ 1.190 + constraint(ALLOC_IN_RC(int_reg)); 1.191 + match(RegN); 1.192 + 1.193 + format %{ %} 1.194 + interface(REG_INTER); 1.195 +%} 1.196 + 1.197 // Long Register 1.198 operand iRegL() %{ 1.199 constraint(ALLOC_IN_RC(long_reg)); 1.200 @@ -5392,9 +5448,30 @@ 1.201 ins_pipe(iload_mem); 1.202 %} 1.203 1.204 +// Load Compressed Pointer 1.205 +instruct loadN(iRegN dst, memory mem) %{ 1.206 + match(Set dst (LoadN mem)); 1.207 + ins_cost(MEMORY_REF_COST); 1.208 + size(4); 1.209 + 1.210 + format %{ "LDUW $mem,$dst\t! compressed ptr" %} 1.211 + ins_encode %{ 1.212 + Register base = as_Register($mem$$base); 1.213 + Register index = as_Register($mem$$index); 1.214 + Register dst = $dst$$Register; 1.215 + if (index != G0) { 1.216 + __ lduw(base, index, dst); 1.217 + } else { 1.218 + __ lduw(base, $mem$$disp, dst); 1.219 + } 1.220 + %} 1.221 + ins_pipe(iload_mem); 1.222 +%} 1.223 + 1.224 // Load Klass Pointer 1.225 instruct loadKlass(iRegP dst, memory mem) %{ 1.226 match(Set dst (LoadKlass mem)); 1.227 + predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow()); 1.228 ins_cost(MEMORY_REF_COST); 1.229 size(4); 1.230 1.231 @@ -5409,6 +5486,30 @@ 1.232 ins_pipe(iload_mem); 1.233 %} 1.234 1.235 +// Load Klass Pointer 1.236 +instruct loadKlassComp(iRegP dst, memory mem) %{ 1.237 + match(Set dst (LoadKlass mem)); 1.238 + predicate(n->in(MemNode::Address)->bottom_type()->is_narrow()); 1.239 + ins_cost(MEMORY_REF_COST); 1.240 + 1.241 + format %{ "LDUW $mem,$dst\t! compressed klass ptr" %} 1.242 + 1.243 + ins_encode %{ 1.244 + Register base = as_Register($mem$$base); 1.245 + Register index = as_Register($mem$$index); 1.246 + Register dst = $dst$$Register; 1.247 + if (index != G0) { 1.248 + __ lduw(base, index, dst); 1.249 + } else { 1.250 + __ lduw(base, $mem$$disp, dst); 1.251 + } 1.252 + // klass oop never null but this is generated for nonheader klass loads 1.253 + // too which can be null. 1.254 + __ decode_heap_oop(dst); 1.255 + %} 1.256 + ins_pipe(iload_mem); 1.257 +%} 1.258 + 1.259 // Load Short (16bit signed) 1.260 instruct loadS(iRegI dst, memory mem) %{ 1.261 match(Set dst (LoadS mem)); 1.262 @@ -5508,6 +5609,24 @@ 1.263 ins_pipe(loadConP_poll); 1.264 %} 1.265 1.266 +instruct loadConN(iRegN dst, immN src) %{ 1.267 + match(Set dst src); 1.268 + ins_cost(DEFAULT_COST * 2); 1.269 + format %{ "SET $src,$dst\t!ptr" %} 1.270 + ins_encode %{ 1.271 + address con = (address)$src$$constant; 1.272 + Register dst = $dst$$Register; 1.273 + if (con == NULL) { 1.274 + __ mov(G0, dst); 1.275 + } else { 1.276 + __ set_oop((jobject)$src$$constant, dst); 1.277 + __ encode_heap_oop(dst); 1.278 + } 1.279 + %} 1.280 + ins_pipe(loadConP); 1.281 + 1.282 +%} 1.283 + 1.284 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ 1.285 // %%% maybe this should work like loadConD 1.286 match(Set dst src); 1.287 @@ -5741,6 +5860,44 @@ 1.288 ins_pipe(istore_mem_zero); 1.289 %} 1.290 1.291 +// Store Compressed Pointer 1.292 +instruct storeN(memory dst, iRegN src) %{ 1.293 + match(Set dst (StoreN dst src)); 1.294 + ins_cost(MEMORY_REF_COST); 1.295 + size(4); 1.296 + 1.297 + format %{ "STW $src,$dst\t! compressed ptr" %} 1.298 + ins_encode %{ 1.299 + Register base = as_Register($dst$$base); 1.300 + Register index = as_Register($dst$$index); 1.301 + Register src = $src$$Register; 1.302 + if (index != G0) { 1.303 + __ stw(src, base, index); 1.304 + } else { 1.305 + __ stw(src, base, $dst$$disp); 1.306 + } 1.307 + %} 1.308 + ins_pipe(istore_mem_spORreg); 1.309 +%} 1.310 + 1.311 +instruct storeN0(memory dst, immN0 src) %{ 1.312 + match(Set dst (StoreN dst src)); 1.313 + ins_cost(MEMORY_REF_COST); 1.314 + size(4); 1.315 + 1.316 + format %{ "STW $src,$dst\t! compressed ptr" %} 1.317 + ins_encode %{ 1.318 + Register base = as_Register($dst$$base); 1.319 + Register index = as_Register($dst$$index); 1.320 + if (index != G0) { 1.321 + __ stw(0, base, index); 1.322 + } else { 1.323 + __ stw(0, base, $dst$$disp); 1.324 + } 1.325 + %} 1.326 + ins_pipe(istore_mem_zero); 1.327 +%} 1.328 + 1.329 // Store Double 1.330 instruct storeD( memory mem, regD src) %{ 1.331 match(Set mem (StoreD mem src)); 1.332 @@ -5798,6 +5955,26 @@ 1.333 ins_pipe(fstoreD_mem_reg); 1.334 %} 1.335 1.336 +// Convert oop pointer into compressed form 1.337 +instruct encodeHeapOop(iRegN dst, iRegP src) %{ 1.338 + match(Set dst (EncodeP src)); 1.339 + format %{ "SRL $src,3,$dst\t encodeHeapOop" %} 1.340 + ins_encode %{ 1.341 + __ encode_heap_oop($src$$Register, $dst$$Register); 1.342 + %} 1.343 + ins_pipe(ialu_reg); 1.344 +%} 1.345 + 1.346 +instruct decodeHeapOop(iRegP dst, iRegN src) %{ 1.347 + match(Set dst (DecodeN src)); 1.348 + format %{ "decode_heap_oop $src, $dst" %} 1.349 + ins_encode %{ 1.350 + __ decode_heap_oop($src$$Register, $dst$$Register); 1.351 + %} 1.352 + ins_pipe(ialu_reg); 1.353 +%} 1.354 + 1.355 + 1.356 // Store Zero into Aligned Packed Bytes 1.357 instruct storeA8B0(memory mem, immI0 zero) %{ 1.358 match(Set mem (Store8B mem zero)); 1.359 @@ -6434,17 +6611,27 @@ 1.360 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ 1.361 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 1.362 effect( USE mem_ptr, KILL ccr, KILL tmp1); 1.363 -#ifdef _LP64 1.364 format %{ 1.365 "MOV $newval,O7\n\t" 1.366 - "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.367 + "CASA_PTR [$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.368 "CMP $oldval,O7\t\t! See if we made progress\n\t" 1.369 "MOV 1,$res\n\t" 1.370 "MOVne xcc,R_G0,$res" 1.371 %} 1.372 +#ifdef _LP64 1.373 ins_encode( enc_casx(mem_ptr, oldval, newval), 1.374 enc_lflags_ne_to_boolean(res) ); 1.375 #else 1.376 + ins_encode( enc_casi(mem_ptr, oldval, newval), 1.377 + enc_iflags_ne_to_boolean(res) ); 1.378 +#endif 1.379 + ins_pipe( long_memory_op ); 1.380 +%} 1.381 + 1.382 +instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp, flagsReg ccr ) %{ 1.383 + match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 1.384 + effect( USE mem_ptr, KILL ccr, KILL tmp); 1.385 + 1.386 format %{ 1.387 "MOV $newval,O7\n\t" 1.388 "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.389 @@ -6452,9 +6639,18 @@ 1.390 "MOV 1,$res\n\t" 1.391 "MOVne icc,R_G0,$res" 1.392 %} 1.393 - ins_encode( enc_casi(mem_ptr, oldval, newval), 1.394 - enc_iflags_ne_to_boolean(res) ); 1.395 -#endif 1.396 + ins_encode %{ 1.397 + Register Rmem = reg_to_register_object($mem_ptr$$reg); 1.398 + Register Rold = reg_to_register_object($oldval$$reg); 1.399 + Register Rnew = reg_to_register_object($newval$$reg); 1.400 + Register Rres = reg_to_register_object($res$$reg); 1.401 + 1.402 + __ cas(Rmem, Rold, Rnew); 1.403 + __ cmp( Rold, Rnew ); 1.404 + __ mov(1, Rres); 1.405 + __ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres ); 1.406 + %} 1.407 + 1.408 ins_pipe( long_memory_op ); 1.409 %} 1.410 1.411 @@ -8607,6 +8803,17 @@ 1.412 ins_pipe(partial_subtype_check_pipe); 1.413 %} 1.414 1.415 + 1.416 +instruct compP_iRegN_immN0(flagsRegP pcc, iRegN op1, immN0 op2 ) %{ 1.417 + match(Set pcc (CmpN op1 op2)); 1.418 + 1.419 + size(4); 1.420 + format %{ "CMP $op1,$op2\t! ptr" %} 1.421 + opcode(Assembler::subcc_op3, Assembler::arith_op); 1.422 + ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) ); 1.423 + ins_pipe(ialu_cconly_reg_imm); 1.424 +%} 1.425 + 1.426 // ============================================================================ 1.427 // inlined locking and unlocking 1.428 1.429 @@ -8648,9 +8855,10 @@ 1.430 ins_pipe(long_memory_op); 1.431 %} 1.432 1.433 -instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{ 1.434 +instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, 1.435 + o7RegI tmp3, flagsReg ccr) %{ 1.436 match(Set result (StrComp str1 str2)); 1.437 - effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr); 1.438 + effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3); 1.439 ins_cost(300); 1.440 format %{ "String Compare $str1,$str2 -> $result" %} 1.441 ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );