src/cpu/sparc/vm/sparc.ad

changeset 2350
2f644f85485d
parent 2270
885e464e1a40
child 2354
5fe0781a8560
     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  %}

mercurial