Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/cpu/sparc/vm/sparc.ad
          +++ new/src/cpu/sparc/vm/sparc.ad
↓ open down ↓ 659 lines elided ↑ open up ↑
 660  660      Node* o = addr->in(3/*AddPNode::Offset*/);
 661  661      offset = o->is_Con() ? o->bottom_type()->is_intptr_t()->get_con() : Type::OffsetBot;
 662  662      atype = a->bottom_type()->is_ptr()->add_offset(offset);
 663  663      assert(atype->isa_oop_ptr(), "still an oop");
 664  664    }
 665  665    offset = atype->is_ptr()->_offset;
 666  666    if (offset != Type::OffsetBot)  offset += disp32;
 667  667    return offset;
 668  668  }
 669  669  
      670 +static inline jdouble replicate_immI(int con, int count, int width) {
      671 +  // Load a constant replicated "count" times with width "width"
      672 +  int bit_width = width * 8;
      673 +  jlong elt_val = con;
      674 +  elt_val &= (((jlong) 1) << bit_width) - 1;  // mask off sign bits
      675 +  jlong val = elt_val;
      676 +  for (int i = 0; i < count - 1; i++) {
      677 +    val <<= bit_width;
      678 +    val |= elt_val;
      679 +  }
      680 +  jdouble dval = *((jdouble*) &val);  // coerce to double type
      681 +  return dval;
      682 +}
      683 +
 670  684  // Standard Sparc opcode form2 field breakdown
 671  685  static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) {
 672  686    f0 &= (1<<19)-1;     // Mask displacement to 19 bits
 673  687    int op = (f30 << 30) |
 674  688             (f29 << 29) |
 675  689             (f25 << 25) |
 676  690             (f22 << 22) |
 677  691             (f20 << 20) |
 678  692             (f19 << 19) |
 679  693             (f0  <<  0);
↓ open down ↓ 321 lines elided ↑ open up ↑
1001 1015  #endif /*ASSERT*/
1002 1016  }
1003 1017  
1004 1018  //=============================================================================
1005 1019  // REQUIRED FUNCTIONALITY for encoding
1006 1020  void emit_lo(CodeBuffer &cbuf, int val) {  }
1007 1021  void emit_hi(CodeBuffer &cbuf, int val) {  }
1008 1022  
1009 1023  
1010 1024  //=============================================================================
     1025 +const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask;
     1026 +
     1027 +void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
     1028 +  emit_constant_table(cbuf);
     1029 +  MacroAssembler _masm(&cbuf);
     1030 +
     1031 +  Register r = as_Register(ra_->get_encode(this));
     1032 +  CodeSection* cs = __ code()->consts();
     1033 +  int consts_size = cs->align_at_start(cs->size());
     1034 +
     1035 +  if (UseRDPCForConstantTableBase) {
     1036 +    int offset = __ offset();
     1037 +    int disp;
     1038 +
     1039 +    // If the displacement from the current PC to the constant table
     1040 +    // base fits into simm13 we set the constant table base to the
     1041 +    // current PC.
     1042 +    if (__ is_simm13(-(consts_size + offset))) {
     1043 +      set_table_base_offset(-(consts_size + offset));
     1044 +      disp = 0;
     1045 +    } else {
     1046 +      // If the offset of the top constant (last entry in the table)
     1047 +      // fits into simm13 we set the constant table base to the actual
     1048 +      // table base.
     1049 +      if (__ is_simm13(top_constant_offset())) {
     1050 +        set_table_base_offset(0);
     1051 +        disp = consts_size + offset;
     1052 +      } else {
     1053 +        // Otherwise we set the constant table base in the middle of the
     1054 +        // constant table.
     1055 +        int half_consts_size = consts_size / 2;
     1056 +        assert(half_consts_size * 2 == consts_size, "sanity");
     1057 +        set_table_base_offset(-half_consts_size);  // table base offset gets added to the load displacement.
     1058 +        disp = half_consts_size + offset;
     1059 +      }
     1060 +    }
     1061 +
     1062 +    __ get_pc(r);
     1063 +
     1064 +    if (disp != 0) {
     1065 +      assert(r != O7, "need temporary");
     1066 +      __ sub(r, __ ensure_simm13_or_reg(disp, O7), r);
     1067 +    }
     1068 +  }
     1069 +  else {
     1070 +    // Materialize the constant table base.
     1071 +    // Set the constant table base in the middle of the constant
     1072 +    // table.
     1073 +    int half_consts_size = consts_size / 2;
     1074 +    assert(half_consts_size * 2 == consts_size, "sanity");
     1075 +    set_table_base_offset(-half_consts_size);  // table base offset gets added to the load displacement.
     1076 +
     1077 +    address baseaddr = cs->start() + half_consts_size;
     1078 +    RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
     1079 +    AddressLiteral base(baseaddr, rspec);
     1080 +    __ set(base, r);
     1081 +  }
     1082 +}
     1083 +
     1084 +uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
     1085 +  Unimplemented();
     1086 +  return 0;
     1087 +}
     1088 +
     1089 +#ifndef PRODUCT
     1090 +void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
     1091 +  char reg[128];
     1092 +  ra_->dump_register(this, reg);
     1093 +  if (UseRDPCForConstantTableBase) {
     1094 +    st->print("RDPC   %s\t! constant table base", reg);
     1095 +  } else {
     1096 +    st->print("SET    &constanttable,%s\t! constant table base", reg);
     1097 +  }
     1098 +}
     1099 +#endif
     1100 +
     1101 +
     1102 +//=============================================================================
1011 1103  
1012 1104  #ifndef PRODUCT
1013 1105  void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
1014 1106    Compile* C = ra_->C;
1015 1107  
1016 1108    for (int i = 0; i < OptoPrologueNops; i++) {
1017 1109      st->print_cr("NOP"); st->print("\t");
1018 1110    }
1019 1111  
1020 1112    if( VerifyThread ) {
↓ open down ↓ 1219 lines elided ↑ open up ↑
2240 2332    enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{
2241 2333      MacroAssembler _masm(&cbuf);
2242 2334      Label &L = *($labl$$label);
2243 2335      Assembler::Predict predict_taken =
2244 2336        cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
2245 2337  
2246 2338      __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L);
2247 2339      __ delayed()->nop();
2248 2340    %}
2249 2341  
2250      -  enc_class jump_enc( iRegX switch_val, o7RegI table) %{
2251      -    MacroAssembler _masm(&cbuf);
2252      -
2253      -    Register switch_reg       = as_Register($switch_val$$reg);
2254      -    Register table_reg        = O7;
2255      -
2256      -    address table_base = __ address_table_constant(_index2label);
2257      -    RelocationHolder rspec = internal_word_Relocation::spec(table_base);
2258      -
2259      -    // Move table address into a register.
2260      -    __ set(table_base, table_reg, rspec);
2261      -
2262      -    // Jump to base address + switch value
2263      -    __ ld_ptr(table_reg, switch_reg, table_reg);
2264      -    __ jmp(table_reg, G0);
2265      -    __ delayed()->nop();
2266      -
2267      -  %}
2268      -
2269 2342    enc_class enc_ba( Label labl ) %{
2270 2343      MacroAssembler _masm(&cbuf);
2271 2344      Label &L = *($labl$$label);
2272 2345      __ ba(false, L);
2273 2346      __ delayed()->nop();
2274 2347    %}
2275 2348  
2276 2349    enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{
2277 2350      MacroAssembler _masm(&cbuf);
2278 2351      Label &L = *$labl$$label;
↓ open down ↓ 98 lines elided ↑ open up ↑
2377 2450               ($dst$$reg << 25) |
2378 2451               (Assembler::movcc_op3 << 19) |
2379 2452               (6 << 16) |                    // cc2 bit for 'xcc'
2380 2453               ($primary << 14) |
2381 2454               (0 << 13) |                    // select register move
2382 2455               (0 << 11) |                    // cc1, cc0 bits for 'icc'
2383 2456               ($src$$reg << 0);
2384 2457      cbuf.insts()->emit_int32(op);
2385 2458    %}
2386 2459  
2387      -  // Utility encoding for loading a 64 bit Pointer into a register
2388      -  // The 64 bit pointer is stored in the generated code stream
2389      -  enc_class SetPtr( immP src, iRegP rd ) %{
2390      -    Register dest = reg_to_register_object($rd$$reg);
2391      -    MacroAssembler _masm(&cbuf);
2392      -    // [RGV] This next line should be generated from ADLC
2393      -    if ( _opnds[1]->constant_is_oop() ) {
2394      -      intptr_t val = $src$$constant;
2395      -      __ set_oop_constant((jobject)val, dest);
2396      -    } else {          // non-oop pointers, e.g. card mark base, heap top
2397      -      __ set($src$$constant, dest);
2398      -    }
2399      -  %}
2400      -
2401 2460    enc_class Set13( immI13 src, iRegI rd ) %{
2402 2461      emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant );
2403 2462    %}
2404 2463  
2405 2464    enc_class SetHi22( immI src, iRegI rd ) %{
2406 2465      emit2_22( cbuf, Assembler::branch_op, $rd$$reg, Assembler::sethi_op2, $src$$constant );
2407 2466    %}
2408 2467  
2409 2468    enc_class Set32( immI src, iRegI rd ) %{
2410 2469      MacroAssembler _masm(&cbuf);
2411 2470      __ set($src$$constant, reg_to_register_object($rd$$reg));
2412 2471    %}
2413 2472  
2414      -  enc_class SetNull( iRegI rd ) %{
2415      -    emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 );
2416      -  %}
2417      -
2418 2473    enc_class call_epilog %{
2419 2474      if( VerifyStackAtCalls ) {
2420 2475        MacroAssembler _masm(&cbuf);
2421 2476        int framesize = ra_->C->frame_slots() << LogBytesPerInt;
2422 2477        Register temp_reg = G3;
2423 2478        __ add(SP, framesize, temp_reg);
2424 2479        __ cmp(temp_reg, FP);
2425 2480        __ breakpoint_trap(Assembler::notEqual, Assembler::ptr_cc);
2426 2481      }
2427 2482    %}
↓ open down ↓ 343 lines elided ↑ open up ↑
2771 2826      Register Rdst = reg_to_register_object($dst$$reg);
2772 2827      FloatRegister Fsrc1 = $primary ? reg_to_SingleFloatRegister_object($src1$$reg)
2773 2828                                       : reg_to_DoubleFloatRegister_object($src1$$reg);
2774 2829      FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg)
2775 2830                                       : reg_to_DoubleFloatRegister_object($src2$$reg);
2776 2831  
2777 2832      // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1)
2778 2833      __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
2779 2834    %}
2780 2835  
2781      -  enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{   // Load Immediate
2782      -    MacroAssembler _masm(&cbuf);
2783      -    Register dest = reg_to_register_object($dst$$reg);
2784      -    Register temp = reg_to_register_object($tmp$$reg);
2785      -    __ set64( $src$$constant, dest, temp );
2786      -  %}
2787      -
2788      -  enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{
2789      -    // Load a constant replicated "count" times with width "width"
2790      -    int bit_width = $width$$constant * 8;
2791      -    jlong elt_val = $src$$constant;
2792      -    elt_val  &= (((jlong)1) << bit_width) - 1; // mask off sign bits
2793      -    jlong val = elt_val;
2794      -    for (int i = 0; i < $count$$constant - 1; i++) {
2795      -        val <<= bit_width;
2796      -        val |= elt_val;
2797      -    }
2798      -    jdouble dval = *(jdouble*)&val; // coerce to double type
2799      -    MacroAssembler _masm(&cbuf);
2800      -    address double_address = __ double_constant(dval);
2801      -    RelocationHolder rspec = internal_word_Relocation::spec(double_address);
2802      -    AddressLiteral addrlit(double_address, rspec);
2803      -
2804      -    __ sethi(addrlit, $tmp$$Register);
2805      -    // XXX This is a quick fix for 6833573.
2806      -    //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
2807      -    __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
2808      -  %}
2809      -
2810 2836    // Compiler ensures base is doubleword aligned and cnt is count of doublewords
2811 2837    enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
2812 2838      MacroAssembler _masm(&cbuf);
2813 2839      Register    nof_bytes_arg   = reg_to_register_object($cnt$$reg);
2814 2840      Register    nof_bytes_tmp    = reg_to_register_object($temp$$reg);
2815 2841      Register    base_pointer_arg = reg_to_register_object($base$$reg);
2816 2842  
2817 2843      Label loop;
2818 2844      __ mov(nof_bytes_arg, nof_bytes_tmp);
2819 2845  
↓ open down ↓ 789 lines elided ↑ open up ↑
3609 3635  // Long Immediate: low 32-bit mask
3610 3636  operand immL_32bits() %{
3611 3637    predicate(n->get_long() == 0xFFFFFFFFL);
3612 3638    match(ConL);
3613 3639    op_cost(0);
3614 3640  
3615 3641    format %{ %}
3616 3642    interface(CONST_INTER);
3617 3643  %}
3618 3644  
     3645 +// Long Immediate: cheap (materialize in <= 3 instructions)
     3646 +operand immL_cheap() %{
     3647 +  predicate(MacroAssembler::size_of_set64(n->get_long()) <= 3);
     3648 +  match(ConL);
     3649 +  op_cost(0);
     3650 +
     3651 +  format %{ %}
     3652 +  interface(CONST_INTER);
     3653 +%}
     3654 +
     3655 +// Long Immediate: expensive (materialize in > 3 instructions)
     3656 +operand immL_expensive() %{
     3657 +  predicate(MacroAssembler::size_of_set64(n->get_long()) > 3);
     3658 +  match(ConL);
     3659 +  op_cost(0);
     3660 +
     3661 +  format %{ %}
     3662 +  interface(CONST_INTER);
     3663 +%}
     3664 +
3619 3665  // Double Immediate
3620 3666  operand immD() %{
3621 3667    match(ConD);
3622 3668  
3623 3669    op_cost(40);
3624 3670    format %{ %}
3625 3671    interface(CONST_INTER);
3626 3672  %}
3627 3673  
3628 3674  operand immD0() %{
↓ open down ↓ 2345 lines elided ↑ open up ↑
5974 6020  
5975 6021  instruct loadConI13( iRegI dst, immI13 src ) %{
5976 6022    match(Set dst src);
5977 6023  
5978 6024    size(4);
5979 6025    format %{ "MOV    $src,$dst" %}
5980 6026    ins_encode( Set13( src, dst ) );
5981 6027    ins_pipe(ialu_imm);
5982 6028  %}
5983 6029  
5984      -instruct loadConP(iRegP dst, immP src) %{
5985      -  match(Set dst src);
     6030 +instruct loadConP(iRegP dst, immP con) %{
     6031 +  match(Set dst con);
     6032 +#ifndef _LP64
5986 6033    ins_cost(DEFAULT_COST * 3/2);
5987      -  format %{ "SET    $src,$dst\t!ptr" %}
5988      -  // This rule does not use "expand" unlike loadConI because then
5989      -  // the result type is not known to be an Oop.  An ADLC
5990      -  // enhancement will be needed to make that work - not worth it!
5991      -
5992      -  ins_encode( SetPtr( src, dst ) );
     6034 +  format %{ "SET    $con,$dst\t!ptr" %}
     6035 +  ins_encode %{
     6036 +    // [RGV] This next line should be generated from ADLC
     6037 +    if (_opnds[1]->constant_is_oop()) {
     6038 +      intptr_t val = $con$$constant;
     6039 +      __ set_oop_constant((jobject) val, $dst$$Register);
     6040 +    } else {          // non-oop pointers, e.g. card mark base, heap top
     6041 +      __ set($con$$constant, $dst$$Register);
     6042 +    }
     6043 +  %}
     6044 +#else
     6045 +  ins_cost(MEMORY_REF_COST);
     6046 +  size(4);
     6047 +  format %{ "LD     [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
     6048 +  ins_encode %{
     6049 +    __ ld_ptr($constanttablebase, $constantoffset($con), $dst$$Register);
     6050 +  %}
     6051 +#endif
5993 6052    ins_pipe(loadConP);
5994      -
5995 6053  %}
5996 6054  
5997 6055  instruct loadConP0(iRegP dst, immP0 src) %{
5998 6056    match(Set dst src);
5999 6057  
6000 6058    size(4);
6001 6059    format %{ "CLR    $dst\t!ptr" %}
6002      -  ins_encode( SetNull( dst ) );
     6060 +  ins_encode %{
     6061 +    __ clr($dst$$Register);
     6062 +  %}
6003 6063    ins_pipe(ialu_imm);
6004 6064  %}
6005 6065  
6006 6066  instruct loadConP_poll(iRegP dst, immP_poll src) %{
6007 6067    match(Set dst src);
6008 6068    ins_cost(DEFAULT_COST);
6009 6069    format %{ "SET    $src,$dst\t!ptr" %}
6010 6070    ins_encode %{
6011 6071      AddressLiteral polling_page(os::get_polling_page());
6012 6072      __ sethi(polling_page, reg_to_register_object($dst$$reg));
6013 6073    %}
6014 6074    ins_pipe(loadConP_poll);
6015 6075  %}
6016 6076  
6017 6077  instruct loadConN0(iRegN dst, immN0 src) %{
6018 6078    match(Set dst src);
6019 6079  
6020 6080    size(4);
6021 6081    format %{ "CLR    $dst\t! compressed NULL ptr" %}
6022      -  ins_encode( SetNull( dst ) );
     6082 +  ins_encode %{
     6083 +    __ clr($dst$$Register);
     6084 +  %}
6023 6085    ins_pipe(ialu_imm);
6024 6086  %}
6025 6087  
6026 6088  instruct loadConN(iRegN dst, immN src) %{
6027 6089    match(Set dst src);
6028 6090    ins_cost(DEFAULT_COST * 3/2);
6029 6091    format %{ "SET    $src,$dst\t! compressed ptr" %}
6030 6092    ins_encode %{
6031 6093      Register dst = $dst$$Register;
6032 6094      __ set_narrow_oop((jobject)$src$$constant, dst);
6033 6095    %}
6034 6096    ins_pipe(ialu_hi_lo_reg);
6035 6097  %}
6036 6098  
6037      -instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
6038      -  // %%% maybe this should work like loadConD
6039      -  match(Set dst src);
     6099 +// Materialize long value (predicated by immL_cheap).
     6100 +instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{
     6101 +  match(Set dst con);
6040 6102    effect(KILL tmp);
6041      -  ins_cost(DEFAULT_COST * 4);
6042      -  format %{ "SET64   $src,$dst KILL $tmp\t! long" %}
6043      -  ins_encode( LdImmL(src, dst, tmp) );
     6103 +  ins_cost(DEFAULT_COST * 3);
     6104 +  format %{ "SET64   $con,$dst KILL $tmp\t! long" %}
     6105 +  ins_encode %{
     6106 +    __ set64($con$$constant, $dst$$Register, $tmp$$Register);
     6107 +  %}
     6108 +  ins_pipe(loadConL);
     6109 +%}
     6110 +
     6111 +// Load long value from constant table (predicated by immL_expensive).
     6112 +instruct loadConL_ldx(iRegL dst, immL_expensive con) %{
     6113 +  match(Set dst con);
     6114 +  ins_cost(MEMORY_REF_COST);
     6115 +  format %{ "LDX     [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %}
     6116 +  ins_encode %{
     6117 +    __ ldx($constanttablebase, $constantoffset($con), $dst$$Register);
     6118 +  %}
6044 6119    ins_pipe(loadConL);
6045 6120  %}
6046 6121  
6047 6122  instruct loadConL0( iRegL dst, immL0 src ) %{
6048 6123    match(Set dst src);
6049 6124    ins_cost(DEFAULT_COST);
6050 6125    size(4);
6051 6126    format %{ "CLR    $dst\t! long" %}
6052 6127    ins_encode( Set13( src, dst ) );
6053 6128    ins_pipe(ialu_imm);
↓ open down ↓ 2 lines elided ↑ open up ↑
6056 6131  instruct loadConL13( iRegL dst, immL13 src ) %{
6057 6132    match(Set dst src);
6058 6133    ins_cost(DEFAULT_COST * 2);
6059 6134  
6060 6135    size(4);
6061 6136    format %{ "MOV    $src,$dst\t! long" %}
6062 6137    ins_encode( Set13( src, dst ) );
6063 6138    ins_pipe(ialu_imm);
6064 6139  %}
6065 6140  
6066      -instruct loadConF(regF dst, immF src, o7RegP tmp) %{
6067      -  match(Set dst src);
6068      -  effect(KILL tmp);
6069      -
6070      -#ifdef _LP64
6071      -  size(8*4);
6072      -#else
6073      -  size(2*4);
6074      -#endif
6075      -
6076      -  format %{ "SETHI  hi(&$src),$tmp\t!get float $src from table\n\t"
6077      -            "LDF    [$tmp+lo(&$src)],$dst" %}
     6141 +instruct loadConF(regF dst, immF con) %{
     6142 +  match(Set dst con);
     6143 +  size(4);
     6144 +  format %{ "LDF    [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %}
6078 6145    ins_encode %{
6079      -    address float_address = __ float_constant($src$$constant);
6080      -    RelocationHolder rspec = internal_word_Relocation::spec(float_address);
6081      -    AddressLiteral addrlit(float_address, rspec);
6082      -
6083      -    __ sethi(addrlit, $tmp$$Register);
6084      -    __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
     6146 +    __ ldf(FloatRegisterImpl::S, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
6085 6147    %}
6086 6148    ins_pipe(loadConFD);
6087 6149  %}
6088 6150  
6089      -instruct loadConD(regD dst, immD src, o7RegP tmp) %{
6090      -  match(Set dst src);
6091      -  effect(KILL tmp);
6092      -
6093      -#ifdef _LP64
6094      -  size(8*4);
6095      -#else
6096      -  size(2*4);
6097      -#endif
6098      -
6099      -  format %{ "SETHI  hi(&$src),$tmp\t!get double $src from table\n\t"
6100      -            "LDDF   [$tmp+lo(&$src)],$dst" %}
     6151 +instruct loadConD(regD dst, immD con) %{
     6152 +  match(Set dst con);
     6153 +  size(4);
     6154 +  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %}
6101 6155    ins_encode %{
6102      -    address double_address = __ double_constant($src$$constant);
6103      -    RelocationHolder rspec = internal_word_Relocation::spec(double_address);
6104      -    AddressLiteral addrlit(double_address, rspec);
6105      -
6106      -    __ sethi(addrlit, $tmp$$Register);
6107 6156      // XXX This is a quick fix for 6833573.
6108      -    //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
6109      -    __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
     6157 +    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
     6158 +    __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), as_DoubleFloatRegister($dst$$reg));
6110 6159    %}
6111 6160    ins_pipe(loadConFD);
6112 6161  %}
6113 6162  
6114 6163  // Prefetch instructions.
6115 6164  // Must be safe to execute with invalid address (cannot fault).
6116 6165  
6117 6166  instruct prefetchr( memory mem ) %{
6118 6167    match( PrefetchRead mem );
6119 6168    ins_cost(MEMORY_REF_COST);
↓ open down ↓ 2431 lines elided ↑ open up ↑
8551 8600  instruct Repl8B_reg(stackSlotD dst, iRegI src) %{
8552 8601    match(Set dst (Replicate8B src));
8553 8602    expand %{
8554 8603      iRegL tmp;
8555 8604      Repl8B_reg_helper(tmp, src);
8556 8605      regL_to_stkD(dst, tmp);
8557 8606    %}
8558 8607  %}
8559 8608  
8560 8609  // Replicate scalar constant to packed byte values in Double register
8561      -instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{
8562      -  match(Set dst (Replicate8B src));
8563      -#ifdef _LP64
8564      -  size(36);
8565      -#else
8566      -  size(8);
8567      -#endif
8568      -  format %{ "SETHI  hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t"
8569      -            "LDDF   [$tmp+lo(&Repl8($src))],$dst" %}
8570      -  ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) );
     8610 +instruct Repl8B_immI(regD dst, immI13 con) %{
     8611 +  match(Set dst (Replicate8B con));
     8612 +  size(4);
     8613 +  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
     8614 +  ins_encode %{
     8615 +    // XXX This is a quick fix for 6833573.
     8616 +    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
     8617 +    __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), as_DoubleFloatRegister($dst$$reg));
     8618 +  %}
8571 8619    ins_pipe(loadConFD);
8572 8620  %}
8573 8621  
8574 8622  // Replicate scalar to packed char values into stack slot
8575 8623  instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{
8576 8624    effect(DEF dst, USE src);
8577 8625    format %{ "SLLX  $src,48,$dst\n\t"
8578 8626              "SRLX  $dst,16,O7\n\t"
8579 8627              "OR    $dst,O7,$dst\n\t"
8580 8628              "SRLX  $dst,32,O7\n\t"
↓ open down ↓ 6 lines elided ↑ open up ↑
8587 8635  instruct Repl4C_reg(stackSlotD dst, iRegI src) %{
8588 8636    match(Set dst (Replicate4C src));
8589 8637    expand %{
8590 8638      iRegL tmp;
8591 8639      Repl4C_reg_helper(tmp, src);
8592 8640      regL_to_stkD(dst, tmp);
8593 8641    %}
8594 8642  %}
8595 8643  
8596 8644  // Replicate scalar constant to packed char values in Double register
8597      -instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{
8598      -  match(Set dst (Replicate4C src));
8599      -#ifdef _LP64
8600      -  size(36);
8601      -#else
8602      -  size(8);
8603      -#endif
8604      -  format %{ "SETHI  hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t"
8605      -            "LDDF   [$tmp+lo(&Repl4($src))],$dst" %}
8606      -  ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
     8645 +instruct Repl4C_immI(regD dst, immI con) %{
     8646 +  match(Set dst (Replicate4C con));
     8647 +  size(4);
     8648 +  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %}
     8649 +  ins_encode %{
     8650 +    // XXX This is a quick fix for 6833573.
     8651 +    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
     8652 +    __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg));
     8653 +  %}
8607 8654    ins_pipe(loadConFD);
8608 8655  %}
8609 8656  
8610 8657  // Replicate scalar to packed short values into stack slot
8611 8658  instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{
8612 8659    effect(DEF dst, USE src);
8613 8660    format %{ "SLLX  $src,48,$dst\n\t"
8614 8661              "SRLX  $dst,16,O7\n\t"
8615 8662              "OR    $dst,O7,$dst\n\t"
8616 8663              "SRLX  $dst,32,O7\n\t"
↓ open down ↓ 6 lines elided ↑ open up ↑
8623 8670  instruct Repl4S_reg(stackSlotD dst, iRegI src) %{
8624 8671    match(Set dst (Replicate4S src));
8625 8672    expand %{
8626 8673      iRegL tmp;
8627 8674      Repl4S_reg_helper(tmp, src);
8628 8675      regL_to_stkD(dst, tmp);
8629 8676    %}
8630 8677  %}
8631 8678  
8632 8679  // Replicate scalar constant to packed short values in Double register
8633      -instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{
8634      -  match(Set dst (Replicate4S src));
8635      -#ifdef _LP64
8636      -  size(36);
8637      -#else
8638      -  size(8);
8639      -#endif
8640      -  format %{ "SETHI  hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t"
8641      -            "LDDF   [$tmp+lo(&Repl4($src))],$dst" %}
8642      -  ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
     8680 +instruct Repl4S_immI(regD dst, immI con) %{
     8681 +  match(Set dst (Replicate4S con));
     8682 +  size(4);
     8683 +  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
     8684 +  ins_encode %{
     8685 +    // XXX This is a quick fix for 6833573.
     8686 +    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
     8687 +    __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg));
     8688 +  %}
8643 8689    ins_pipe(loadConFD);
8644 8690  %}
8645 8691  
8646 8692  // Replicate scalar to packed int values in Double register
8647 8693  instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{
8648 8694    effect(DEF dst, USE src);
8649 8695    format %{ "SLLX  $src,32,$dst\n\t"
8650 8696              "SRLX  $dst,32,O7\n\t"
8651 8697              "OR    $dst,O7,$dst\t! replicate2I" %}
8652 8698    ins_encode( enc_repl2i(src, dst));
↓ open down ↓ 4 lines elided ↑ open up ↑
8657 8703  instruct Repl2I_reg(stackSlotD dst, iRegI src) %{
8658 8704    match(Set dst (Replicate2I src));
8659 8705    expand %{
8660 8706      iRegL tmp;
8661 8707      Repl2I_reg_helper(tmp, src);
8662 8708      regL_to_stkD(dst, tmp);
8663 8709    %}
8664 8710  %}
8665 8711  
8666 8712  // Replicate scalar zero constant to packed int values in Double register
8667      -instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{
8668      -  match(Set dst (Replicate2I src));
8669      -#ifdef _LP64
8670      -  size(36);
8671      -#else
8672      -  size(8);
8673      -#endif
8674      -  format %{ "SETHI  hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t"
8675      -            "LDDF   [$tmp+lo(&Repl2($src))],$dst" %}
8676      -  ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) );
     8713 +instruct Repl2I_immI(regD dst, immI con) %{
     8714 +  match(Set dst (Replicate2I con));
     8715 +  size(4);
     8716 +  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
     8717 +  ins_encode %{
     8718 +    // XXX This is a quick fix for 6833573.
     8719 +    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
     8720 +    __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), as_DoubleFloatRegister($dst$$reg));
     8721 +  %}
8677 8722    ins_pipe(loadConFD);
8678 8723  %}
8679 8724  
8680 8725  //----------Control Flow Instructions------------------------------------------
8681 8726  // Compare Instructions
8682 8727  // Compare Integers
8683 8728  instruct compI_iReg(flagsReg icc, iRegI op1, iRegI op2) %{
8684 8729    match(Set icc (CmpI op1 op2));
8685 8730    effect( DEF icc, USE op1, USE op2 );
8686 8731  
↓ open down ↓ 235 lines elided ↑ open up ↑
8922 8967  %}
8923 8968  
8924 8969  //----------Branches---------------------------------------------------------
8925 8970  // Jump
8926 8971  // (compare 'operand indIndex' and 'instruct addP_reg_reg' above)
8927 8972  instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
8928 8973    match(Jump switch_val);
8929 8974  
8930 8975    ins_cost(350);
8931 8976  
8932      -  format %{  "SETHI  [hi(table_base)],O7\n\t"
8933      -             "ADD    O7, lo(table_base), O7\n\t"
8934      -             "LD     [O7+$switch_val], O7\n\t"
     8977 +  format %{  "ADD    $constanttablebase, $constantoffset, O7\n\t"
     8978 +             "LD     [O7 + $switch_val], O7\n\t"
8935 8979               "JUMP   O7"
8936 8980           %}
8937      -  ins_encode( jump_enc( switch_val, table) );
     8981 +  ins_encode %{
     8982 +    // Calculate table address into a register.
     8983 +    Register table_reg;
     8984 +    Register label_reg = O7;
     8985 +    if (constant_offset() == 0) {
     8986 +      table_reg = $constanttablebase;
     8987 +    } else {
     8988 +      table_reg = O7;
     8989 +      __ add($constanttablebase, $constantoffset, table_reg);
     8990 +    }
     8991 +
     8992 +    // Jump to base address + switch value
     8993 +    __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
     8994 +    __ jmp(label_reg, G0);
     8995 +    __ delayed()->nop();
     8996 +  %}
8938 8997    ins_pc_relative(1);
8939 8998    ins_pipe(ialu_reg_reg);
8940 8999  %}
8941 9000  
8942 9001  // Direct Branch.  Use V8 version with longer range.
8943 9002  instruct branch(label labl) %{
8944 9003    match(Goto);
8945 9004    effect(USE labl);
8946 9005  
8947 9006    size(8);
↓ open down ↓ 966 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX