src/cpu/sparc/vm/sparc.ad

changeset 548
ba764ed4b6f2
parent 516
dee7a3f3dc9d
child 559
b130b98db9cf
     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) );

mercurial