hotspot/src/cpu/sparc/vm/sparc.ad

Print this page
rev 611 : Merge

@@ -1,7 +1,7 @@
 //
-// Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+// Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License version 2 only, as
 // published by the Free Software Foundation.

@@ -393,10 +393,11 @@
                    ,R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5
 #endif // _LP64
                   );
 
 reg_class g1_regL(R_G1H,R_G1);
+reg_class g3_regL(R_G3H,R_G3);
 reg_class o2_regL(R_O2H,R_O2);
 reg_class o7_regL(R_O7H,R_O7);
 
 // ----------------------------
 // Special Class for Condition Code Flags Register

@@ -466,12 +467,10 @@
 #define LONG_LO_REG(x) (x)
 
 %}
 
 source %{
-#pragma ident "@(#)sparc.ad     1.456 07/09/28 10:23:30 JVM"
-
 #define __ _masm.
 
 // tertiary op of a LoadP or StoreP encoding
 #define REGP_OP true
 

@@ -544,15 +543,23 @@
            NativeCall::instruction_size);  // sethi; setlo; call; delay slot
   } else {
     assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
     int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
     int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+    int klass_load_size;
+    if (UseCompressedOops) {
+      klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass()
+    } else {
+      klass_load_size = 1*BytesPerInstWord;
+    }
     if( Assembler::is_simm13(v_off) ) {
-      return (3*BytesPerInstWord +           // ld_ptr, ld_ptr, ld_ptr
+      return klass_load_size +
+             (2*BytesPerInstWord +           // ld_ptr, ld_ptr
              NativeCall::instruction_size);  // call; delay slot
     } else {
-      return (5*BytesPerInstWord +           // ld_ptr, set_hi, set, ld_ptr, ld_ptr
+      return klass_load_size +
+             (4*BytesPerInstWord +           // set_hi, set, ld_ptr, ld_ptr
              NativeCall::instruction_size);  // call; delay slot
     }
   }
 }
 

@@ -1591,11 +1598,17 @@
 //=============================================================================
 #ifndef PRODUCT
 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
   st->print_cr("\nUEP:");
 #ifdef    _LP64
+  if (UseCompressedOops) {
+    st->print_cr("\tLDUW   [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
+    st->print_cr("\tSLL    R_G5,3,R_G5");
+    st->print_cr("\tADD    R_G5,R_G6_heap_base,R_G5");
+  } else {
   st->print_cr("\tLDX    [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
+  }
   st->print_cr("\tCMP    R_G5,R_G3" );
   st->print   ("\tTne    xcc,R_G0+ST_RESERVED_FOR_USER_0+2");
 #else  // _LP64
   st->print_cr("\tLDUW   [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
   st->print_cr("\tCMP    R_G5,R_G3" );

@@ -1610,11 +1623,11 @@
   Register G5_ic_reg  = reg_to_register_object(Matcher::inline_cache_reg_encode());
   Register temp_reg   = G3;
   assert( G5_ic_reg != temp_reg, "conflicting registers" );
 
   // Load klass from reciever
-  __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
+  __ load_klass(O0, temp_reg);
   // Compare against expected klass
   __ cmp(temp_reg, G5_ic_reg);
   // Branch to miss code, checks xcc or icc depending
   __ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2);
 }

@@ -1729,11 +1742,11 @@
 
 // Is this branch offset short enough that a short branch can be used?
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
   return false;
 }
 
 const bool Matcher::isSimpleConstant64(jlong value) {
   // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.

@@ -1811,10 +1824,15 @@
       reg == R_I1H_num ||
       reg == R_I2H_num ||
       reg == R_I3H_num ||
       reg == R_I4H_num ||
       reg == R_I5H_num ) return true;
+
+  if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) {
+    return true;
+  }
+
 #else
   // 32-bit builds with longs-in-one-entry pass longs in G1 & G4.
   // Longs cannot be passed in O regs, because O regs become I regs
   // after a 'save' and I regs get their high bits chopped off on
   // interrupt.

@@ -1907,48 +1925,53 @@
   enc_class form3_mem_reg( memory mem, iRegI dst ) %{
     emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
                        $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
   %}
 
+  enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
+                       $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+  %}
+
   enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
-    emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
                      $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
   %}
 
   enc_class form3_mem_prefetch_read( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
   %}
 
   enc_class form3_mem_prefetch_write( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
   %}
 
   enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{
     assert( Assembler::is_simm13($mem$$disp  ), "need disp and disp+4" );
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
     emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
     emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc ); 
   %}
 
   enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{
     assert( Assembler::is_simm13($mem$$disp  ), "need disp and disp+4" );
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
     // Load long with 2 instructions
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
   %}
 
   //%%% form3_mem_plus_4_reg is a hack--get rid of it
   enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
     guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
   %}
 
   enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
     // Encode a reg-reg copy.  If it is useless, then empty encoding.
     if( $rs2$$reg != $rd$$reg ) 

@@ -2474,21 +2497,28 @@
       assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
       // Just go thru the vtable
       // get receiver klass (receiver already checked for non-null)
       // If we end up going thru a c2i adapter interpreter expects method in G5
       int off = __ offset();
-      __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+      __ load_klass(O0, G3_scratch);
+      int klass_load_size;
+      if (UseCompressedOops) {
+        klass_load_size = 3*BytesPerInstWord;
+      } else {
+        klass_load_size = 1*BytesPerInstWord;
+      }
       int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
       int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
       if( __ is_simm13(v_off) ) {
         __ ld_ptr(G3, v_off, G5_method);
       } else {
         // Generate 2 instructions
         __ Assembler::sethi(v_off & ~0x3ff, G5_method);
         __ or3(G5_method, v_off & 0x3ff, G5_method);
         // ld_ptr, set_hi, set
-        assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)");
+        assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord,
+               "Unexpected instruction size(s)");
         __ ld_ptr(G3, G5_method, G5_method);
       }
       // NOTE: for vtable dispatches, the vtable entry will never be null.
       // However it may very well end up in handle_wrong_method if the
       // method is abstract for the particular class. 

@@ -2657,11 +2687,11 @@
     assert(Roop  != Rscratch, "");
     assert(Roop  != Rmark, "");
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
+    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
 %}
 
 enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
     MacroAssembler _masm(&cbuf);
 

@@ -2673,11 +2703,11 @@
     assert(Roop  != Rscratch, "");
     assert(Roop  != Rmark, "");
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
+    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
   %}
 
   enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
     MacroAssembler _masm(&cbuf);
     Register Rmem = reg_to_register_object($mem$$reg);

@@ -2685,12 +2715,11 @@
     Register Rnew = reg_to_register_object($new$$reg);
 
     // casx_under_lock picks 1 of 3 encodings:
     // For 32-bit pointers you get a 32-bit CAS
     // For 64-bit pointers you get a 64-bit CASX
-    __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
-                        (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+    __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
     __ cmp( Rold, Rnew );
   %}
 
   enc_class enc_casx( iRegP mem, iRegL old, iRegL new) %{
     Register Rmem = reg_to_register_object($mem$$reg);

@@ -2860,16 +2889,16 @@
     int  value_offset = java_lang_String:: value_offset_in_bytes();
     int offset_offset = java_lang_String::offset_offset_in_bytes();
     int  count_offset = java_lang_String:: count_offset_in_bytes();
 
     // load str1 (jchar*) base address into tmp1_reg
-    __ ld_ptr(Address(str1_reg, 0,  value_offset), tmp1_reg);
+    __ load_heap_oop(Address(str1_reg, 0,  value_offset), tmp1_reg);
     __ ld(Address(str1_reg, 0, offset_offset), result_reg);
     __ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
     __    ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted
     __ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
-    __    ld_ptr(Address(str2_reg, 0,  value_offset), tmp2_reg); // hoisted
+    __    load_heap_oop(Address(str2_reg, 0,  value_offset), tmp2_reg); // hoisted
     __ add(result_reg, tmp1_reg, tmp1_reg);
 
     // load str2 (jchar*) base address into tmp2_reg
     // __ ld_ptr(Address(str2_reg, 0,  value_offset), tmp2_reg); // hoisted
     __ ld(Address(str2_reg, 0, offset_offset), result_reg);

@@ -3016,10 +3045,11 @@
 
   enc_class enc_membar_volatile %{
     MacroAssembler _masm(&cbuf);
     __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) );
   %}
+
   enc_class enc_repl8b( iRegI src, iRegL dst ) %{
     MacroAssembler _masm(&cbuf);
     Register src_reg = reg_to_register_object($src$$reg);
     Register dst_reg = reg_to_register_object($dst$$reg);
     __ sllx(src_reg, 56, dst_reg);

@@ -3189,37 +3219,37 @@
   // to and from the register pairs is done by the appropriate call and epilog
   // opcodes.  This simplifies the register allocator.
   c_return_value %{
     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
 #ifdef     _LP64
-    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 };
-    static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num,    OptoReg::Bad, R_F1_num, R_O0H_num};
-    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 };
-    static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num,    OptoReg::Bad, R_F1_num, R_I0H_num};
+    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 };
+    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};
+    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 };
+    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};
 #else  // !_LP64
-    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 };
-    static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
-    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 };
-    static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
+    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 };
+    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 };
+    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 };
+    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 };
 #endif
     return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 
                         (is_outgoing?lo_out:lo_in)[ideal_reg] );
   %}
 
   // Location of compiled Java return values.  Same as C
   return_value %{
     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
 #ifdef     _LP64
-    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 };
-    static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num,    OptoReg::Bad, R_F1_num, R_O0H_num};
-    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 };
-    static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num,    OptoReg::Bad, R_F1_num, R_I0H_num};
+    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 };
+    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};
+    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 };
+    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};
 #else  // !_LP64
-    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 };
-    static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
-    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 };
-    static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
+    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 };
+    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};
+    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 };
+    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};
 #endif
     return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg], 
                         (is_outgoing?lo_out:lo_in)[ideal_reg] );
   %}
 

@@ -3408,10 +3438,31 @@
   // formats are generated automatically for constants and base registers
   format %{ %}                
   interface(CONST_INTER);
 %}
 
+// Pointer Immediate
+operand immN()
+%{
+  match(ConN);
+
+  op_cost(10);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+// NULL Pointer Immediate
+operand immN0()
+%{
+  predicate(n->get_narrowcon() == 0);
+  match(ConN);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 operand immL() %{
   match(ConL);
   op_cost(40);
   // formats are generated automatically for constants and base registers
   format %{ %}                

@@ -3672,10 +3723,18 @@
 
   format %{ %}
   interface(REG_INTER);
 %}
 
+operand iRegN() %{
+  constraint(ALLOC_IN_RC(int_reg));
+  match(RegN);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 // Long Register
 operand iRegL() %{
   constraint(ALLOC_IN_RC(long_reg));
   match(RegL);
 

@@ -3705,10 +3764,18 @@
 
   format %{ %}
   interface(REG_INTER);
 %}
 
+operand g3RegL() %{
+  constraint(ALLOC_IN_RC(g3_regL));
+  match(iRegL);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 // Int Register safe
 // This is 64bit safe
 operand iRegIsafe() %{
   constraint(ALLOC_IN_RC(long_reg));
 

@@ -5006,66 +5073,66 @@
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDF    $src,$dst\t! stkI to regF" %}
   opcode(Assembler::ldf_op3); 
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
 instruct stkL_to_regD(regD dst, stackSlotL src) %{
   // No match rule to avoid chain rule match.
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDDF   $src,$dst\t! stkL to regD" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
 instruct regF_to_stkI(stackSlotI dst, regF src) %{
   // No match rule to avoid chain rule match.
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STF    $src,$dst\t! regF to stkI" %}
   opcode(Assembler::stf_op3); 
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
 instruct regD_to_stkL(stackSlotL dst, regD src) %{
   // No match rule to avoid chain rule match.
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STDF   $src,$dst\t! regD to stkL" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
 instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST*2);
   size(8);
   format %{ "STW    $src,$dst.hi\t! long\n\t"
             "STW    R_G0,$dst.lo" %}
   opcode(Assembler::stw_op3);
-  ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+  ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
   ins_pipe(lstoreI_stk_reg);
 %}
 
 instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
   // No match rule to avoid chain rule match.
   effect(DEF dst, USE src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $src,$dst\t! regL to stkD" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_stk_reg);
 %}
 
 //---------- Chain stack slots between similar types --------
 

@@ -5075,11 +5142,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUW   $src,$dst\t!stk" %}
   opcode(Assembler::lduw_op3); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Store integer to stack slot
 instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{

@@ -5087,11 +5154,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STW    $src,$dst\t!stk" %}
   opcode(Assembler::stw_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 // Load long from stack slot
 instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{

@@ -5099,11 +5166,11 @@
 
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDX    $src,$dst\t! long" %}
   opcode(Assembler::ldx_op3); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Store long to stack slot
 instruct regL_to_stkL(stackSlotL dst, iRegL src) %{

@@ -5111,11 +5178,11 @@
 
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $src,$dst\t! long" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 #ifdef _LP64
 // Load pointer from stack slot, 64-bit encoding

@@ -5123,42 +5190,42 @@
   match(Set dst src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDX    $src,$dst\t!ptr" %}
   opcode(Assembler::ldx_op3); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Store pointer to stack slot
 instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
   match(Set dst src);
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $src,$dst\t!ptr" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #else // _LP64
 // Load pointer from stack slot, 32-bit encoding
 instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
   match(Set dst src);
   ins_cost(MEMORY_REF_COST);
   format %{ "LDUW   $src,$dst\t!ptr" %}
   opcode(Assembler::lduw_op3, Assembler::ldst_op); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Store pointer to stack slot
 instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
   match(Set dst src);
   ins_cost(MEMORY_REF_COST);
   format %{ "STW    $src,$dst\t!ptr" %}
   opcode(Assembler::stw_op3, Assembler::ldst_op); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #endif // _LP64
 
 //------------Special Nop instructions for bundling - no match rules-----------

@@ -5217,11 +5284,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDSB   $mem,$dst" %}       
   opcode(Assembler::ldsb_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Byte (8bit UNsigned) into an int reg
 instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{

@@ -5229,11 +5296,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUB   $mem,$dst" %}       
   opcode(Assembler::ldub_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Byte (8bit UNsigned) into a Long Register
 instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{

@@ -5241,11 +5308,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUB   $mem,$dst" %}     
   opcode(Assembler::ldub_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Char (16bit UNsigned) into a Long Register
 instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{

@@ -5253,11 +5320,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Char (16bit unsigned)
 instruct loadC(iRegI dst, memory mem) %{

@@ -5265,11 +5332,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUH   $mem,$dst" %}       
   opcode(Assembler::lduh_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Integer
 instruct loadI(iRegI dst, memory mem) %{

@@ -5277,22 +5344,22 @@
   ins_cost(MEMORY_REF_COST);
   size(4);
 
   format %{ "LDUW   $mem,$dst" %}       
   opcode(Assembler::lduw_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Load Long - aligned
 instruct loadL(iRegL dst, memory mem ) %{
   match(Set dst (LoadL mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Load Long - UNaligned
 instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{

@@ -5303,55 +5370,55 @@
   format %{ "LDUW   $mem+4,R_O7\t! misaligned long\n"
           "\tLDUW   $mem  ,$dst\n"
           "\tSLLX   #32, $dst, $dst\n"
           "\tOR     $dst, R_O7, $dst" %}
   opcode(Assembler::lduw_op3); 
-  ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+  ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
   ins_pipe(iload_mem);
 %}
 
 // Load Aligned Packed Byte into a Double Register
 instruct loadA8B(regD dst, memory mem) %{
   match(Set dst (Load8B mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed8B" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
 // Load Aligned Packed Char into a Double Register
 instruct loadA4C(regD dst, memory mem) %{
   match(Set dst (Load4C mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4C" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
 // Load Aligned Packed Short into a Double Register
 instruct loadA4S(regD dst, memory mem) %{
   match(Set dst (Load4S mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4S" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
 // Load Aligned Packed Int into a Double Register
 instruct loadA2I(regD dst, memory mem) %{
   match(Set dst (Load2I mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed2I" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
 // Load Range
 instruct loadRange(iRegI dst, memory mem) %{

@@ -5359,11 +5426,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUW   $mem,$dst\t! range" %}
   opcode(Assembler::lduw_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
 // Load Integer into %f register (for fitos/fitod)
 instruct loadI_freg(regF dst, memory mem) %{

@@ -5371,11 +5438,11 @@
   ins_cost(MEMORY_REF_COST);
   size(4);
 
   format %{ "LDF    $mem,$dst\t! for fitos/fitod" %}
   opcode(Assembler::ldf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
 // Load Pointer
 instruct loadP(iRegP dst, memory mem) %{

@@ -5392,10 +5459,30 @@
 #endif
   ins_encode( form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
+// Load Compressed Pointer
+instruct loadN(iRegN dst, memory mem) %{
+   match(Set dst (LoadN mem));
+   ins_cost(MEMORY_REF_COST);
+   size(4);
+
+   format %{ "LDUW   $mem,$dst\t! compressed ptr" %}
+   ins_encode %{
+     Register base = as_Register($mem$$base);
+     Register index = as_Register($mem$$index);
+     Register dst = $dst$$Register;
+     if (index != G0) {
+       __ lduw(base, index, dst);
+     } else {
+       __ lduw(base, $mem$$disp, dst);
+     }
+   %}
+   ins_pipe(iload_mem);
+%}
+
 // Load Klass Pointer
 instruct loadKlass(iRegP dst, memory mem) %{
   match(Set dst (LoadKlass mem));
   ins_cost(MEMORY_REF_COST);
   size(4);

@@ -5409,19 +5496,40 @@
 #endif
   ins_encode( form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
+// Load narrow Klass Pointer
+instruct loadNKlass(iRegN dst, memory mem) %{
+  match(Set dst (LoadNKlass mem));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+
+  format %{ "LDUW   $mem,$dst\t! compressed klass ptr" %}
+
+  ins_encode %{
+     Register base = as_Register($mem$$base);
+     Register index = as_Register($mem$$index);
+     Register dst = $dst$$Register;
+     if (index != G0) {
+       __ lduw(base, index, dst);
+     } else {
+       __ lduw(base, $mem$$disp, dst);
+     }
+  %}
+  ins_pipe(iload_mem);
+%}
+
 // Load Short (16bit signed)
 instruct loadS(iRegI dst, memory mem) %{
   match(Set dst (LoadS mem));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDSH   $mem,$dst" %}       
   opcode(Assembler::ldsh_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
 // Load Double
 instruct loadD(regD dst, memory mem) %{

@@ -5429,11 +5537,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDDF   $mem,$dst" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
 // Load Double - UNaligned
 instruct loadD_unaligned(regD_low dst, memory mem ) %{

@@ -5453,11 +5561,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDF    $mem,$dst" %}
   opcode(Assembler::ldf_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
 // Load Constant
 instruct loadConI( iRegI dst, immI src ) %{

@@ -5508,10 +5616,30 @@
     __ sethi(polling_page, false );
   %}
   ins_pipe(loadConP_poll);
 %}
 
+instruct loadConN0(iRegN dst, immN0 src) %{
+  match(Set dst src);
+
+  size(4);
+  format %{ "CLR    $dst\t! compressed NULL ptr" %}
+  ins_encode( SetNull( dst ) );
+  ins_pipe(ialu_imm);
+%}
+
+instruct loadConN(iRegN dst, immN src) %{
+  match(Set dst src);
+  ins_cost(DEFAULT_COST * 3/2);
+  format %{ "SET    $src,$dst\t! compressed ptr" %}
+  ins_encode %{
+    Register dst = $dst$$Register;
+    __ set_narrow_oop((jobject)$src$$constant, dst);
+  %}
+  ins_pipe(ialu_hi_lo_reg);
+%}
+
 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
   // %%% maybe this should work like loadConD
   match(Set dst src);
   effect(KILL tmp);
   ins_cost(DEFAULT_COST * 4);

@@ -5602,33 +5730,33 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 instruct storeB0(memory mem, immI0 src) %{
   match(Set mem (StoreB mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
 instruct storeCM0(memory mem, immI0 src) %{
   match(Set mem (StoreCM mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STB    $src,$mem\t! CMS card-mark byte 0" %}
   opcode(Assembler::stb_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
 // Store Char/Short
 instruct storeC(memory mem, iRegI src) %{

@@ -5636,22 +5764,22 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 instruct storeC0(memory mem, immI0 src) %{
   match(Set mem (StoreC mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
 // Store Integer
 instruct storeI(memory mem, iRegI src) %{

@@ -5659,44 +5787,44 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 // Store Long
 instruct storeL(memory mem, iRegL src) %{
   match(Set mem (StoreL mem src));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $src,$mem\t! long" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 instruct storeI0(memory mem, immI0 src) %{
   match(Set mem (StoreI mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
 instruct storeL0(memory mem, immL0 src) %{
   match(Set mem (StoreL mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
 // Store Integer from float register (used after fstoi)
 instruct storeI_Freg(memory mem, regF src) %{

@@ -5704,11 +5832,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STF    $src,$mem\t! after fstoi/fdtoi" %}
   opcode(Assembler::stf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
 // Store Pointer
 instruct storeP(memory dst, sp_ptr_RegP src) %{

@@ -5741,30 +5869,68 @@
 #endif
   ins_encode( form3_mem_reg( dst, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
+// Store Compressed Pointer
+instruct storeN(memory dst, iRegN src) %{
+   match(Set dst (StoreN dst src));
+   ins_cost(MEMORY_REF_COST);
+   size(4);
+
+   format %{ "STW    $src,$dst\t! compressed ptr" %}
+   ins_encode %{
+     Register base = as_Register($dst$$base);
+     Register index = as_Register($dst$$index);
+     Register src = $src$$Register;
+     if (index != G0) {
+       __ stw(src, base, index);
+     } else {
+       __ stw(src, base, $dst$$disp);
+     }
+   %}
+   ins_pipe(istore_mem_spORreg);
+%}
+
+instruct storeN0(memory dst, immN0 src) %{
+   match(Set dst (StoreN dst src));
+   ins_cost(MEMORY_REF_COST);
+   size(4);
+
+   format %{ "STW    $src,$dst\t! compressed ptr" %}
+   ins_encode %{
+     Register base = as_Register($dst$$base);
+     Register index = as_Register($dst$$index);
+     if (index != G0) {
+       __ stw(0, base, index);
+     } else {
+       __ stw(0, base, $dst$$disp);
+     }
+   %}
+   ins_pipe(istore_mem_zero);
+%}
+
 // Store Double
 instruct storeD( memory mem, regD src) %{
   match(Set mem (StoreD mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STDF   $src,$mem" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
 instruct storeD0( memory mem, immD0 src) %{
   match(Set mem (StoreD mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
 // Store Float
 instruct storeF( memory mem, regF src) %{

@@ -5772,88 +5938,132 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STF    $src,$mem" %}
   opcode(Assembler::stf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
 instruct storeF0( memory mem, immF0 src) %{
   match(Set mem (StoreF mem src));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STW    $src,$mem\t! storeF0" %}
   opcode(Assembler::stw_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreF_mem_zero);
 %}
 
 // Store Aligned Packed Bytes in Double register to memory
 instruct storeA8B(memory mem, regD src) %{
   match(Set mem (Store8B mem src));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STDF   $src,$mem\t! packed8B" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
+// Convert oop pointer into compressed form
+instruct encodeHeapOop(iRegN dst, iRegP src) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
+  match(Set dst (EncodeP src));
+  format %{ "encode_heap_oop $src, $dst" %}
+  ins_encode %{
+    __ encode_heap_oop($src$$Register, $dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
+  match(Set dst (EncodeP src));
+  format %{ "encode_heap_oop_not_null $src, $dst" %}
+  ins_encode %{
+    __ encode_heap_oop_not_null($src$$Register, $dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct decodeHeapOop(iRegP dst, iRegN src) %{
+  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+            n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
+  match(Set dst (DecodeN src));
+  format %{ "decode_heap_oop $src, $dst" %}
+  ins_encode %{
+    __ decode_heap_oop($src$$Register, $dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
+  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+            n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
+  match(Set dst (DecodeN src));
+  format %{ "decode_heap_oop_not_null $src, $dst" %}
+  ins_encode %{
+    __ decode_heap_oop_not_null($src$$Register, $dst$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+
 // Store Zero into Aligned Packed Bytes
 instruct storeA8B0(memory mem, immI0 zero) %{
   match(Set mem (Store8B mem zero));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $zero,$mem\t! packed8B" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
 // Store Aligned Packed Chars/Shorts in Double register to memory
 instruct storeA4C(memory mem, regD src) %{
   match(Set mem (Store4C mem src));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STDF   $src,$mem\t! packed4C" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
 // Store Zero into Aligned Packed Chars/Shorts
 instruct storeA4C0(memory mem, immI0 zero) %{
   match(Set mem (Store4C mem (Replicate4C zero)));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $zero,$mem\t! packed4C" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
 // Store Aligned Packed Ints in Double register to memory
 instruct storeA2I(memory mem, regD src) %{
   match(Set mem (Store2I mem src));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STDF   $src,$mem\t! packed2I" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
 // Store Zero into Aligned Packed Ints
 instruct storeA2I0(memory mem, immI0 zero) %{
   match(Set mem (Store2I mem zero));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "STX    $zero,$mem\t! packed2I" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
 
 //----------MemBar Instructions-----------------------------------------------

@@ -5963,31 +6173,31 @@
   // %%%% TO DO: Tell the coalescer that this kind of node is a copy!
   match(Set stkSlot src);   // chain rule
   ins_cost(MEMORY_REF_COST);
   format %{ "STDF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
 instruct ldfSSD(regD dst, stackSlotD stkSlot) %{
   // %%%% TO DO: Tell the coalescer that this kind of node is a copy!
   match(Set dst stkSlot);   // chain rule
   ins_cost(MEMORY_REF_COST);
   format %{ "LDDF   $stkSlot,$dst\t!stk" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode(form3_mem_reg(stkSlot, dst));
+  ins_encode(simple_form3_mem_reg(stkSlot, dst));
   ins_pipe(floadD_stk);
 %}
 
 instruct stfSSF(stackSlotF stkSlot, regF src) %{
   // %%%% TO DO: Tell the coalescer that this kind of node is a copy!
   match(Set stkSlot src);   // chain rule
   ins_cost(MEMORY_REF_COST);
   format %{ "STF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stf_op3); 
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
 //----------Conditional Move---------------------------------------------------
 // Conditional move

@@ -6023,20 +6233,20 @@
   format %{ "MOV$cmp  $icc,$src,$dst" %}
   ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) );
   ins_pipe(ialu_imm);
 %}
 
-instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{
+instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
   ins_cost(150);
   size(4);
   format %{ "MOV$cmp  $icc,$src,$dst" %}
   ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
   ins_pipe(ialu_reg);
 %}
 
-instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{
+instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
   match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
   ins_cost(140);
   size(4);
   format %{ "MOV$cmp  $icc,$src,$dst" %}
   ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) );

@@ -6059,10 +6269,38 @@
   format %{ "MOV$cmp $fcc,$src,$dst" %}
   ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) );
   ins_pipe(ialu_imm);
 %}
 
+// Conditional move for RegN. Only cmov(reg,reg).
+instruct cmovNP_reg(cmpOpP cmp, flagsRegP pcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp pcc) (Binary dst src)));
+  ins_cost(150);
+  format %{ "MOV$cmp $pcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) );
+  ins_pipe(ialu_reg);
+%}
+
+// This instruction also works with CmpN so we don't need cmovNN_reg.
+instruct cmovNI_reg(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp icc) (Binary dst src)));
+  ins_cost(150);
+  size(4);
+  format %{ "MOV$cmp  $icc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+  ins_pipe(ialu_reg);
+%}
+
+instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src)));
+  ins_cost(150);
+  size(4);
+  format %{ "MOV$cmp $fcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) );
+  ins_pipe(ialu_reg);
+%}
+
 // Conditional move
 instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
   ins_cost(150);
   format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %}

@@ -6076,10 +6314,11 @@
   format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %}
   ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) );
   ins_pipe(ialu_imm);
 %}
 
+// This instruction also works with CmpN so we don't need cmovPN_reg.
 instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
   ins_cost(150);
 
   size(4);

@@ -6356,11 +6595,11 @@
   match(Set dst (LoadLLocked mem));
   ins_cost(MEMORY_REF_COST);
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3); 
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
 instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{
   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));

@@ -6369,36 +6608,27 @@
             "CMP    R_G3,$oldval\t\t! See if we made progress"  %}
   ins_encode( enc_cas(heap_top_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect( USE mem_ptr, KILL ccr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t" 
-            "CMP    $oldval,R_O7\t\t! See if we made progress\n\t"
-            "MOV    1,$res\n\t"
-            "MOVne  xcc,R_G0,$res"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval),
-              enc_lflags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
+  match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
-  match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-  effect( USE mem_ptr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t" 
-            "CMP    $oldval,R_O7\t\t! See if we made progress"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval));
+// Conditional-store of a long value.
+instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
+  match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 

@@ -6434,31 +6664,39 @@
 %}
 
 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
-#ifdef _LP64
   format %{
             "MOV    $newval,O7\n\t"
-            "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" 
+            "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"
             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
             "MOV    1,$res\n\t"
             "MOVne  xcc,R_G0,$res"
   %}
+#ifdef _LP64
   ins_encode( enc_casx(mem_ptr, oldval, newval),
               enc_lflags_ne_to_boolean(res) );
 #else
+  ins_encode( enc_casi(mem_ptr, oldval, newval),
+              enc_iflags_ne_to_boolean(res) );
+#endif
+  ins_pipe( long_memory_op );
+%}
+
+instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
+  match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
+  effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
             "MOV    $newval,O7\n\t"
             "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" 
             "CMP    $oldval,O7\t\t! See if we made progress\n\t"
             "MOV    1,$res\n\t"
             "MOVne  icc,R_G0,$res"
   %}
   ins_encode( enc_casi(mem_ptr, oldval, newval),
               enc_iflags_ne_to_boolean(res) );
-#endif
   ins_pipe( long_memory_op );
 %}
 
 //---------------------
 // Subtraction Instructions

@@ -7169,10 +7407,38 @@
   opcode(Assembler::or_op3, Assembler::arith_op); 
   ins_encode( form3_rs1_simm13_rd( src1, con, dst ) );
   ins_pipe(ialu_reg_imm);
 %}
 
+#ifndef _LP64
+
+// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
+instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrI src1 (CastP2X src2)));
+
+  size(4);
+  format %{ "OR     $src1,$src2,$dst" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#else
+
+instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrL src1 (CastP2X src2)));
+
+  ins_cost(DEFAULT_COST);
+  size(4);
+  format %{ "OR     $src1,$src2,$dst\t! long" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#endif
+
 // Xor Instructions
 // Register Xor
 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
   match(Set dst (XorI src1 src2));
 

@@ -7430,11 +7696,11 @@
   ins_cost(DEFAULT_COST + MEMORY_REF_COST);
   size(8);
   format %{ "LDF    $mem,$dst\n\t"
             "FITOD  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitod_opf); 
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
 
 instruct convI2F_helper(regF dst, regF tmp) %{

@@ -7460,11 +7726,11 @@
   ins_cost(DEFAULT_COST + MEMORY_REF_COST);
   size(8);
   format %{ "LDF    $mem,$dst\n\t"
             "FITOS  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitos_opf); 
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
 
 instruct convI2L_reg(iRegL dst, iRegI src) %{

@@ -7502,11 +7768,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDUW   $src,$dst\t! MoveF2I" %}
   opcode(Assembler::lduw_op3); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
   match(Set dst (MoveI2F src));

@@ -7514,11 +7780,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDF    $src,$dst\t! MoveI2F" %}
   opcode(Assembler::ldf_op3); 
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
   match(Set dst (MoveD2L src));

@@ -7526,11 +7792,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDX    $src,$dst\t! MoveD2L" %}
   opcode(Assembler::ldx_op3); 
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
   match(Set dst (MoveL2D src));

@@ -7538,11 +7804,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "LDDF   $src,$dst\t! MoveL2D" %}
   opcode(Assembler::lddf_op3); 
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
   match(Set dst (MoveF2I src));

@@ -7550,11 +7816,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STF   $src,$dst\t!MoveF2I" %}
   opcode(Assembler::stf_op3); 
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
   match(Set dst (MoveI2F src));

@@ -7562,11 +7828,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STW    $src,$dst\t!MoveI2F" %}
   opcode(Assembler::stw_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
   match(Set dst (MoveD2L src));

@@ -7574,11 +7840,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STDF   $src,$dst\t!MoveD2L" %}
   opcode(Assembler::stdf_op3); 
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
   match(Set dst (MoveL2D src));

@@ -7586,11 +7852,11 @@
   ins_cost(MEMORY_REF_COST);
 
   size(4);
   format %{ "STX    $src,$dst\t!MoveL2D" %}
   opcode(Assembler::stx_op3); 
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
 
 //-----------

@@ -8047,10 +8313,31 @@
   opcode(Assembler::subcc_op3, Assembler::arith_op); 
   ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
   ins_pipe(ialu_cconly_reg_imm);
 %}
 
+// Compare Narrow oops
+instruct compN_iRegN(flagsReg icc, iRegN op1, iRegN op2 ) %{
+  match(Set icc (CmpN op1 op2));
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! compressed ptr" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) );
+  ins_pipe(ialu_cconly_reg_reg);
+%}
+
+instruct compN_iRegN_immN0(flagsReg icc, iRegN op1, immN0 op2 ) %{
+  match(Set icc (CmpN op1 op2));
+
+  size(4);
+  format %{ "CMP    $op1,$op2\t! compressed ptr" %}
+  opcode(Assembler::subcc_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
+  ins_pipe(ialu_cconly_reg_imm);
+%}
+
 //----------Max and Min--------------------------------------------------------
 // Min Instructions
 // Conditional move for min
 instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
   effect( USE_DEF op2, USE op1, USE icc );

@@ -8377,10 +8664,18 @@
   format %{ "MOV$cmp  $xcc,$src,$dst" %}
   ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) );
   ins_pipe(ialu_imm);
 %}
 
+instruct cmovNL_reg(cmpOp cmp, flagsRegL xcc, iRegN dst, iRegN src) %{
+  match(Set dst (CMoveN (Binary cmp xcc) (Binary dst src)));
+  ins_cost(150);
+  format %{ "MOV$cmp  $xcc,$src,$dst" %}
+  ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );
+  ins_pipe(ialu_reg);
+%}
+
 instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{
   match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
   ins_cost(150);
   format %{ "MOV$cmp  $xcc,$src,$dst" %}
   ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );

@@ -8607,10 +8902,11 @@
   format %{ "CALL   PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %}
   ins_encode( enc_PartialSubtypeCheck() );
   ins_pipe(partial_subtype_check_pipe);
 %}
 
+
 // ============================================================================
 // inlined locking and unlocking
 
 instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
   match(Set pcc (FastLock object box));

@@ -8648,13 +8944,14 @@
     "        STX    G0,[$base+$temp]\t! delay slot" %}
   ins_encode( enc_Clear_Array(cnt, base, temp) );
   ins_pipe(long_memory_op);                                                         
 %}
 
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{
+instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
+                        o7RegI tmp3, flagsReg ccr) %{
   match(Set result (StrComp str1 str2));
-  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr);
+  effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
   ins_cost(300);
   format %{ "String Compare $str1,$str2 -> $result" %}
   ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
   ins_pipe(long_memory_op);
 %}