1.1 --- a/src/cpu/sparc/vm/sparc.ad Thu Dec 02 17:21:12 2010 -0800 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Fri Dec 03 01:34:31 2010 -0800 1.3 @@ -667,6 +667,20 @@ 1.4 return offset; 1.5 } 1.6 1.7 +static inline jdouble replicate_immI(int con, int count, int width) { 1.8 + // Load a constant replicated "count" times with width "width" 1.9 + int bit_width = width * 8; 1.10 + jlong elt_val = con; 1.11 + elt_val &= (((jlong) 1) << bit_width) - 1; // mask off sign bits 1.12 + jlong val = elt_val; 1.13 + for (int i = 0; i < count - 1; i++) { 1.14 + val <<= bit_width; 1.15 + val |= elt_val; 1.16 + } 1.17 + jdouble dval = *((jdouble*) &val); // coerce to double type 1.18 + return dval; 1.19 +} 1.20 + 1.21 // Standard Sparc opcode form2 field breakdown 1.22 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) { 1.23 f0 &= (1<<19)-1; // Mask displacement to 19 bits 1.24 @@ -1008,6 +1022,90 @@ 1.25 1.26 1.27 //============================================================================= 1.28 +const bool Matcher::constant_table_absolute_addressing = false; 1.29 +const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask; 1.30 + 1.31 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1.32 + Compile* C = ra_->C; 1.33 + Compile::ConstantTable& constant_table = C->constant_table(); 1.34 + MacroAssembler _masm(&cbuf); 1.35 + 1.36 + Register r = as_Register(ra_->get_encode(this)); 1.37 + CodeSection* cs = __ code()->consts(); 1.38 + int consts_size = cs->align_at_start(cs->size()); 1.39 + 1.40 + if (UseRDPCForConstantTableBase) { 1.41 + // For the following RDPC logic to work correctly the consts 1.42 + // section must be allocated right before the insts section. This 1.43 + // assert checks for that. The layout and the SECT_* constants 1.44 + // are defined in src/share/vm/asm/codeBuffer.hpp. 1.45 + assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be"); 1.46 + int offset = __ offset(); 1.47 + int disp; 1.48 + 1.49 + // If the displacement from the current PC to the constant table 1.50 + // base fits into simm13 we set the constant table base to the 1.51 + // current PC. 1.52 + if (__ is_simm13(-(consts_size + offset))) { 1.53 + constant_table.set_table_base_offset(-(consts_size + offset)); 1.54 + disp = 0; 1.55 + } else { 1.56 + // If the offset of the top constant (last entry in the table) 1.57 + // fits into simm13 we set the constant table base to the actual 1.58 + // table base. 1.59 + if (__ is_simm13(constant_table.top_offset())) { 1.60 + constant_table.set_table_base_offset(0); 1.61 + disp = consts_size + offset; 1.62 + } else { 1.63 + // Otherwise we set the constant table base in the middle of the 1.64 + // constant table. 1.65 + int half_consts_size = consts_size / 2; 1.66 + assert(half_consts_size * 2 == consts_size, "sanity"); 1.67 + constant_table.set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement. 1.68 + disp = half_consts_size + offset; 1.69 + } 1.70 + } 1.71 + 1.72 + __ rdpc(r); 1.73 + 1.74 + if (disp != 0) { 1.75 + assert(r != O7, "need temporary"); 1.76 + __ sub(r, __ ensure_simm13_or_reg(disp, O7), r); 1.77 + } 1.78 + } 1.79 + else { 1.80 + // Materialize the constant table base. 1.81 + assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size)); 1.82 + address baseaddr = cs->start() + -(constant_table.table_base_offset()); 1.83 + RelocationHolder rspec = internal_word_Relocation::spec(baseaddr); 1.84 + AddressLiteral base(baseaddr, rspec); 1.85 + __ set(base, r); 1.86 + } 1.87 +} 1.88 + 1.89 +uint MachConstantBaseNode::size(PhaseRegAlloc*) const { 1.90 + if (UseRDPCForConstantTableBase) { 1.91 + // This is really the worst case but generally it's only 1 instruction. 1.92 + return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set(); 1.93 + } else { 1.94 + return MacroAssembler::worst_case_size_of_set(); 1.95 + } 1.96 +} 1.97 + 1.98 +#ifndef PRODUCT 1.99 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1.100 + char reg[128]; 1.101 + ra_->dump_register(this, reg); 1.102 + if (UseRDPCForConstantTableBase) { 1.103 + st->print("RDPC %s\t! constant table base", reg); 1.104 + } else { 1.105 + st->print("SET &constanttable,%s\t! constant table base", reg); 1.106 + } 1.107 +} 1.108 +#endif 1.109 + 1.110 + 1.111 +//============================================================================= 1.112 1.113 #ifndef PRODUCT 1.114 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1.115 @@ -2247,25 +2345,6 @@ 1.116 __ delayed()->nop(); 1.117 %} 1.118 1.119 - enc_class jump_enc( iRegX switch_val, o7RegI table) %{ 1.120 - MacroAssembler _masm(&cbuf); 1.121 - 1.122 - Register switch_reg = as_Register($switch_val$$reg); 1.123 - Register table_reg = O7; 1.124 - 1.125 - address table_base = __ address_table_constant(_index2label); 1.126 - RelocationHolder rspec = internal_word_Relocation::spec(table_base); 1.127 - 1.128 - // Move table address into a register. 1.129 - __ set(table_base, table_reg, rspec); 1.130 - 1.131 - // Jump to base address + switch value 1.132 - __ ld_ptr(table_reg, switch_reg, table_reg); 1.133 - __ jmp(table_reg, G0); 1.134 - __ delayed()->nop(); 1.135 - 1.136 - %} 1.137 - 1.138 enc_class enc_ba( Label labl ) %{ 1.139 MacroAssembler _masm(&cbuf); 1.140 Label &L = *($labl$$label); 1.141 @@ -2384,20 +2463,6 @@ 1.142 cbuf.insts()->emit_int32(op); 1.143 %} 1.144 1.145 - // Utility encoding for loading a 64 bit Pointer into a register 1.146 - // The 64 bit pointer is stored in the generated code stream 1.147 - enc_class SetPtr( immP src, iRegP rd ) %{ 1.148 - Register dest = reg_to_register_object($rd$$reg); 1.149 - MacroAssembler _masm(&cbuf); 1.150 - // [RGV] This next line should be generated from ADLC 1.151 - if ( _opnds[1]->constant_is_oop() ) { 1.152 - intptr_t val = $src$$constant; 1.153 - __ set_oop_constant((jobject)val, dest); 1.154 - } else { // non-oop pointers, e.g. card mark base, heap top 1.155 - __ set($src$$constant, dest); 1.156 - } 1.157 - %} 1.158 - 1.159 enc_class Set13( immI13 src, iRegI rd ) %{ 1.160 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant ); 1.161 %} 1.162 @@ -2411,10 +2476,6 @@ 1.163 __ set($src$$constant, reg_to_register_object($rd$$reg)); 1.164 %} 1.165 1.166 - enc_class SetNull( iRegI rd ) %{ 1.167 - emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 ); 1.168 - %} 1.169 - 1.170 enc_class call_epilog %{ 1.171 if( VerifyStackAtCalls ) { 1.172 MacroAssembler _masm(&cbuf); 1.173 @@ -2778,35 +2839,6 @@ 1.174 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 1.175 %} 1.176 1.177 - enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate 1.178 - MacroAssembler _masm(&cbuf); 1.179 - Register dest = reg_to_register_object($dst$$reg); 1.180 - Register temp = reg_to_register_object($tmp$$reg); 1.181 - __ set64( $src$$constant, dest, temp ); 1.182 - %} 1.183 - 1.184 - enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{ 1.185 - // Load a constant replicated "count" times with width "width" 1.186 - int bit_width = $width$$constant * 8; 1.187 - jlong elt_val = $src$$constant; 1.188 - elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits 1.189 - jlong val = elt_val; 1.190 - for (int i = 0; i < $count$$constant - 1; i++) { 1.191 - val <<= bit_width; 1.192 - val |= elt_val; 1.193 - } 1.194 - jdouble dval = *(jdouble*)&val; // coerce to double type 1.195 - MacroAssembler _masm(&cbuf); 1.196 - address double_address = __ double_constant(dval); 1.197 - RelocationHolder rspec = internal_word_Relocation::spec(double_address); 1.198 - AddressLiteral addrlit(double_address, rspec); 1.199 - 1.200 - __ sethi(addrlit, $tmp$$Register); 1.201 - // XXX This is a quick fix for 6833573. 1.202 - //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 1.203 - __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); 1.204 - %} 1.205 - 1.206 // Compiler ensures base is doubleword aligned and cnt is count of doublewords 1.207 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ 1.208 MacroAssembler _masm(&cbuf); 1.209 @@ -3521,6 +3553,29 @@ 1.210 interface(CONST_INTER); 1.211 %} 1.212 1.213 +// Pointer Immediate: 32 or 64-bit 1.214 +operand immP_set() %{ 1.215 + predicate(!VM_Version::is_niagara1_plus()); 1.216 + match(ConP); 1.217 + 1.218 + op_cost(5); 1.219 + // formats are generated automatically for constants and base registers 1.220 + format %{ %} 1.221 + interface(CONST_INTER); 1.222 +%} 1.223 + 1.224 +// Pointer Immediate: 32 or 64-bit 1.225 +// From Niagara2 processors on a load should be better than materializing. 1.226 +operand immP_load() %{ 1.227 + predicate(VM_Version::is_niagara1_plus()); 1.228 + match(ConP); 1.229 + 1.230 + op_cost(5); 1.231 + // formats are generated automatically for constants and base registers 1.232 + format %{ %} 1.233 + interface(CONST_INTER); 1.234 +%} 1.235 + 1.236 operand immP13() %{ 1.237 predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095)); 1.238 match(ConP); 1.239 @@ -3616,6 +3671,26 @@ 1.240 interface(CONST_INTER); 1.241 %} 1.242 1.243 +// Long Immediate: cheap (materialize in <= 3 instructions) 1.244 +operand immL_cheap() %{ 1.245 + predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3); 1.246 + match(ConL); 1.247 + op_cost(0); 1.248 + 1.249 + format %{ %} 1.250 + interface(CONST_INTER); 1.251 +%} 1.252 + 1.253 +// Long Immediate: expensive (materialize in > 3 instructions) 1.254 +operand immL_expensive() %{ 1.255 + predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3); 1.256 + match(ConL); 1.257 + op_cost(0); 1.258 + 1.259 + format %{ %} 1.260 + interface(CONST_INTER); 1.261 +%} 1.262 + 1.263 // Double Immediate 1.264 operand immD() %{ 1.265 match(ConD); 1.266 @@ -5981,25 +6056,58 @@ 1.267 ins_pipe(ialu_imm); 1.268 %} 1.269 1.270 -instruct loadConP(iRegP dst, immP src) %{ 1.271 - match(Set dst src); 1.272 +#ifndef _LP64 1.273 +instruct loadConP(iRegP dst, immP con) %{ 1.274 + match(Set dst con); 1.275 ins_cost(DEFAULT_COST * 3/2); 1.276 - format %{ "SET $src,$dst\t!ptr" %} 1.277 - // This rule does not use "expand" unlike loadConI because then 1.278 - // the result type is not known to be an Oop. An ADLC 1.279 - // enhancement will be needed to make that work - not worth it! 1.280 - 1.281 - ins_encode( SetPtr( src, dst ) ); 1.282 + format %{ "SET $con,$dst\t!ptr" %} 1.283 + ins_encode %{ 1.284 + // [RGV] This next line should be generated from ADLC 1.285 + if (_opnds[1]->constant_is_oop()) { 1.286 + intptr_t val = $con$$constant; 1.287 + __ set_oop_constant((jobject) val, $dst$$Register); 1.288 + } else { // non-oop pointers, e.g. card mark base, heap top 1.289 + __ set($con$$constant, $dst$$Register); 1.290 + } 1.291 + %} 1.292 ins_pipe(loadConP); 1.293 - 1.294 -%} 1.295 +%} 1.296 +#else 1.297 +instruct loadConP_set(iRegP dst, immP_set con) %{ 1.298 + match(Set dst con); 1.299 + ins_cost(DEFAULT_COST * 3/2); 1.300 + format %{ "SET $con,$dst\t! ptr" %} 1.301 + ins_encode %{ 1.302 + // [RGV] This next line should be generated from ADLC 1.303 + if (_opnds[1]->constant_is_oop()) { 1.304 + intptr_t val = $con$$constant; 1.305 + __ set_oop_constant((jobject) val, $dst$$Register); 1.306 + } else { // non-oop pointers, e.g. card mark base, heap top 1.307 + __ set($con$$constant, $dst$$Register); 1.308 + } 1.309 + %} 1.310 + ins_pipe(loadConP); 1.311 +%} 1.312 + 1.313 +instruct loadConP_load(iRegP dst, immP_load con) %{ 1.314 + match(Set dst con); 1.315 + ins_cost(MEMORY_REF_COST); 1.316 + format %{ "LD [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %} 1.317 + ins_encode %{ 1.318 + __ ld_ptr($constanttablebase, $constantoffset($con), $dst$$Register); 1.319 + %} 1.320 + ins_pipe(loadConP); 1.321 +%} 1.322 +#endif // _LP64 1.323 1.324 instruct loadConP0(iRegP dst, immP0 src) %{ 1.325 match(Set dst src); 1.326 1.327 size(4); 1.328 format %{ "CLR $dst\t!ptr" %} 1.329 - ins_encode( SetNull( dst ) ); 1.330 + ins_encode %{ 1.331 + __ clr($dst$$Register); 1.332 + %} 1.333 ins_pipe(ialu_imm); 1.334 %} 1.335 1.336 @@ -6019,7 +6127,9 @@ 1.337 1.338 size(4); 1.339 format %{ "CLR $dst\t! compressed NULL ptr" %} 1.340 - ins_encode( SetNull( dst ) ); 1.341 + ins_encode %{ 1.342 + __ clr($dst$$Register); 1.343 + %} 1.344 ins_pipe(ialu_imm); 1.345 %} 1.346 1.347 @@ -6034,13 +6144,26 @@ 1.348 ins_pipe(ialu_hi_lo_reg); 1.349 %} 1.350 1.351 -instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ 1.352 - // %%% maybe this should work like loadConD 1.353 - match(Set dst src); 1.354 +// Materialize long value (predicated by immL_cheap). 1.355 +instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{ 1.356 + match(Set dst con); 1.357 effect(KILL tmp); 1.358 - ins_cost(DEFAULT_COST * 4); 1.359 - format %{ "SET64 $src,$dst KILL $tmp\t! long" %} 1.360 - ins_encode( LdImmL(src, dst, tmp) ); 1.361 + ins_cost(DEFAULT_COST * 3); 1.362 + format %{ "SET64 $con,$dst KILL $tmp\t! cheap long" %} 1.363 + ins_encode %{ 1.364 + __ set64($con$$constant, $dst$$Register, $tmp$$Register); 1.365 + %} 1.366 + ins_pipe(loadConL); 1.367 +%} 1.368 + 1.369 +// Load long value from constant table (predicated by immL_expensive). 1.370 +instruct loadConL_ldx(iRegL dst, immL_expensive con) %{ 1.371 + match(Set dst con); 1.372 + ins_cost(MEMORY_REF_COST); 1.373 + format %{ "LDX [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %} 1.374 + ins_encode %{ 1.375 + __ ldx($constanttablebase, $constantoffset($con), $dst$$Register); 1.376 + %} 1.377 ins_pipe(loadConL); 1.378 %} 1.379 1.380 @@ -6063,50 +6186,24 @@ 1.381 ins_pipe(ialu_imm); 1.382 %} 1.383 1.384 -instruct loadConF(regF dst, immF src, o7RegP tmp) %{ 1.385 - match(Set dst src); 1.386 - effect(KILL tmp); 1.387 - 1.388 -#ifdef _LP64 1.389 - size(8*4); 1.390 -#else 1.391 - size(2*4); 1.392 -#endif 1.393 - 1.394 - format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t" 1.395 - "LDF [$tmp+lo(&$src)],$dst" %} 1.396 +instruct loadConF(regF dst, immF con) %{ 1.397 + match(Set dst con); 1.398 + size(4); 1.399 + format %{ "LDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %} 1.400 ins_encode %{ 1.401 - address float_address = __ float_constant($src$$constant); 1.402 - RelocationHolder rspec = internal_word_Relocation::spec(float_address); 1.403 - AddressLiteral addrlit(float_address, rspec); 1.404 - 1.405 - __ sethi(addrlit, $tmp$$Register); 1.406 - __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 1.407 + __ ldf(FloatRegisterImpl::S, $constanttablebase, $constantoffset($con), $dst$$FloatRegister); 1.408 %} 1.409 ins_pipe(loadConFD); 1.410 %} 1.411 1.412 -instruct loadConD(regD dst, immD src, o7RegP tmp) %{ 1.413 - match(Set dst src); 1.414 - effect(KILL tmp); 1.415 - 1.416 -#ifdef _LP64 1.417 - size(8*4); 1.418 -#else 1.419 - size(2*4); 1.420 -#endif 1.421 - 1.422 - format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t" 1.423 - "LDDF [$tmp+lo(&$src)],$dst" %} 1.424 +instruct loadConD(regD dst, immD con) %{ 1.425 + match(Set dst con); 1.426 + size(4); 1.427 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %} 1.428 ins_encode %{ 1.429 - address double_address = __ double_constant($src$$constant); 1.430 - RelocationHolder rspec = internal_word_Relocation::spec(double_address); 1.431 - AddressLiteral addrlit(double_address, rspec); 1.432 - 1.433 - __ sethi(addrlit, $tmp$$Register); 1.434 // XXX This is a quick fix for 6833573. 1.435 - //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 1.436 - __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); 1.437 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister); 1.438 + __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), as_DoubleFloatRegister($dst$$reg)); 1.439 %} 1.440 ins_pipe(loadConFD); 1.441 %} 1.442 @@ -8558,16 +8655,15 @@ 1.443 %} 1.444 1.445 // Replicate scalar constant to packed byte values in Double register 1.446 -instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{ 1.447 - match(Set dst (Replicate8B src)); 1.448 -#ifdef _LP64 1.449 - size(36); 1.450 -#else 1.451 - size(8); 1.452 -#endif 1.453 - format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t" 1.454 - "LDDF [$tmp+lo(&Repl8($src))],$dst" %} 1.455 - ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) ); 1.456 +instruct Repl8B_immI(regD dst, immI13 con) %{ 1.457 + match(Set dst (Replicate8B con)); 1.458 + size(4); 1.459 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %} 1.460 + ins_encode %{ 1.461 + // XXX This is a quick fix for 6833573. 1.462 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister); 1.463 + __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), as_DoubleFloatRegister($dst$$reg)); 1.464 + %} 1.465 ins_pipe(loadConFD); 1.466 %} 1.467 1.468 @@ -8594,16 +8690,15 @@ 1.469 %} 1.470 1.471 // Replicate scalar constant to packed char values in Double register 1.472 -instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{ 1.473 - match(Set dst (Replicate4C src)); 1.474 -#ifdef _LP64 1.475 - size(36); 1.476 -#else 1.477 - size(8); 1.478 -#endif 1.479 - format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t" 1.480 - "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 1.481 - ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 1.482 +instruct Repl4C_immI(regD dst, immI con) %{ 1.483 + match(Set dst (Replicate4C con)); 1.484 + size(4); 1.485 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %} 1.486 + ins_encode %{ 1.487 + // XXX This is a quick fix for 6833573. 1.488 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister); 1.489 + __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg)); 1.490 + %} 1.491 ins_pipe(loadConFD); 1.492 %} 1.493 1.494 @@ -8630,16 +8725,15 @@ 1.495 %} 1.496 1.497 // Replicate scalar constant to packed short values in Double register 1.498 -instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{ 1.499 - match(Set dst (Replicate4S src)); 1.500 -#ifdef _LP64 1.501 - size(36); 1.502 -#else 1.503 - size(8); 1.504 -#endif 1.505 - format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t" 1.506 - "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 1.507 - ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 1.508 +instruct Repl4S_immI(regD dst, immI con) %{ 1.509 + match(Set dst (Replicate4S con)); 1.510 + size(4); 1.511 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %} 1.512 + ins_encode %{ 1.513 + // XXX This is a quick fix for 6833573. 1.514 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister); 1.515 + __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg)); 1.516 + %} 1.517 ins_pipe(loadConFD); 1.518 %} 1.519 1.520 @@ -8664,16 +8758,15 @@ 1.521 %} 1.522 1.523 // Replicate scalar zero constant to packed int values in Double register 1.524 -instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{ 1.525 - match(Set dst (Replicate2I src)); 1.526 -#ifdef _LP64 1.527 - size(36); 1.528 -#else 1.529 - size(8); 1.530 -#endif 1.531 - format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t" 1.532 - "LDDF [$tmp+lo(&Repl2($src))],$dst" %} 1.533 - ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) ); 1.534 +instruct Repl2I_immI(regD dst, immI con) %{ 1.535 + match(Set dst (Replicate2I con)); 1.536 + size(4); 1.537 + format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %} 1.538 + ins_encode %{ 1.539 + // XXX This is a quick fix for 6833573. 1.540 + //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister); 1.541 + __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), as_DoubleFloatRegister($dst$$reg)); 1.542 + %} 1.543 ins_pipe(loadConFD); 1.544 %} 1.545 1.546 @@ -8929,12 +9022,26 @@ 1.547 1.548 ins_cost(350); 1.549 1.550 - format %{ "SETHI [hi(table_base)],O7\n\t" 1.551 - "ADD O7, lo(table_base), O7\n\t" 1.552 - "LD [O7+$switch_val], O7\n\t" 1.553 + format %{ "ADD $constanttablebase, $constantoffset, O7\n\t" 1.554 + "LD [O7 + $switch_val], O7\n\t" 1.555 "JUMP O7" 1.556 %} 1.557 - ins_encode( jump_enc( switch_val, table) ); 1.558 + ins_encode %{ 1.559 + // Calculate table address into a register. 1.560 + Register table_reg; 1.561 + Register label_reg = O7; 1.562 + if (constant_offset() == 0) { 1.563 + table_reg = $constanttablebase; 1.564 + } else { 1.565 + table_reg = O7; 1.566 + __ add($constanttablebase, $constantoffset, table_reg); 1.567 + } 1.568 + 1.569 + // Jump to base address + switch value 1.570 + __ ld_ptr(table_reg, $switch_val$$Register, label_reg); 1.571 + __ jmp(label_reg, G0); 1.572 + __ delayed()->nop(); 1.573 + %} 1.574 ins_pc_relative(1); 1.575 ins_pipe(ialu_reg_reg); 1.576 %}