hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
changeset 7427 d7b79a367474
parent 7397 5b173b4ca846
child 7432 f06f1253c317
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 23 13:22:55 2010 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 30 23:23:40 2010 -0800
@@ -100,6 +100,11 @@
         return false;
       }
 
+      if (UseCompressedOops) {
+        if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
+        if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
+      }
+
       if (dst->is_register()) {
         if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
           return !PatchALot;
@@ -253,7 +258,7 @@
     int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
     int  count_offset = java_lang_String:: count_offset_in_bytes();
 
-    __ ld_ptr(str0, value_offset, tmp0);
+    __ load_heap_oop(str0, value_offset, tmp0);
     __ ld(str0, offset_offset, tmp2);
     __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
     __ ld(str0, count_offset, str0);
@@ -262,7 +267,7 @@
     // str1 may be null
     add_debug_info_for_null_check_here(info);
 
-    __ ld_ptr(str1, value_offset, tmp1);
+    __ load_heap_oop(str1, value_offset, tmp1);
     __ add(tmp0, tmp2, tmp0);
 
     __ ld(str1, offset_offset, tmp2);
@@ -766,7 +771,7 @@
 
 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
   add_debug_info_for_null_check_here(op->info());
-  __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+  __ load_klass(O0, G3_scratch);
   if (__ is_simm13(op->vtable_offset())) {
     __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
   } else {
@@ -780,138 +785,17 @@
   // the peephole pass fills the delay slot
 }
 
-
-// load with 32-bit displacement
-int LIR_Assembler::load(Register s, int disp, Register d, BasicType ld_type, CodeEmitInfo *info) {
-  int load_offset = code_offset();
-  if (Assembler::is_simm13(disp)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    switch(ld_type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ ldsb(s, disp, d); break;
-      case T_CHAR  : __ lduh(s, disp, d); break;
-      case T_SHORT : __ ldsh(s, disp, d); break;
-      case T_INT   : __ ld(s, disp, d); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(s, disp, d); break;
-      default      : ShouldNotReachHere();
-    }
-  } else {
-    __ set(disp, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    load_offset = code_offset();
-    switch(ld_type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ ldsb(s, O7, d); break;
-      case T_CHAR  : __ lduh(s, O7, d); break;
-      case T_SHORT : __ ldsh(s, O7, d); break;
-      case T_INT   : __ ld(s, O7, d); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(s, O7, d); break;
-      default      : ShouldNotReachHere();
-    }
-  }
-  if (ld_type == T_ARRAY || ld_type == T_OBJECT) __ verify_oop(d);
-  return load_offset;
-}
-
-
-// store with 32-bit displacement
-void LIR_Assembler::store(Register value, Register base, int offset, BasicType type, CodeEmitInfo *info) {
-  if (Assembler::is_simm13(offset)) {
-    if (info != NULL)  add_debug_info_for_null_check_here(info);
-    switch (type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ stb(value, base, offset); break;
-      case T_CHAR  : __ sth(value, base, offset); break;
-      case T_SHORT : __ sth(value, base, offset); break;
-      case T_INT   : __ stw(value, base, offset); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : // fall through
-      case T_OBJECT: __ st_ptr(value, base, offset); break;
-      default      : ShouldNotReachHere();
-    }
-  } else {
-    __ set(offset, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    switch (type) {
-      case T_BOOLEAN: // fall through
-      case T_BYTE  : __ stb(value, base, O7); break;
-      case T_CHAR  : __ sth(value, base, O7); break;
-      case T_SHORT : __ sth(value, base, O7); break;
-      case T_INT   : __ stw(value, base, O7); break;
-      case T_ADDRESS:// fall through
-      case T_ARRAY : //fall through
-      case T_OBJECT: __ st_ptr(value, base, O7); break;
-      default      : ShouldNotReachHere();
-    }
-  }
-  // Note: Do the store before verification as the code might be patched!
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(value);
-}
-
-
-// load float with 32-bit displacement
-void LIR_Assembler::load(Register s, int disp, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) {
-  FloatRegisterImpl::Width w;
-  switch(ld_type) {
-    case T_FLOAT : w = FloatRegisterImpl::S; break;
-    case T_DOUBLE: w = FloatRegisterImpl::D; break;
-    default      : ShouldNotReachHere();
-  }
-
-  if (Assembler::is_simm13(disp)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    if (disp % BytesPerLong != 0 && w == FloatRegisterImpl::D) {
-      __ ldf(FloatRegisterImpl::S, s, disp + BytesPerWord, d->successor());
-      __ ldf(FloatRegisterImpl::S, s, disp               , d);
-    } else {
-      __ ldf(w, s, disp, d);
-    }
-  } else {
-    __ set(disp, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    __ ldf(w, s, O7, d);
-  }
-}
-
-
-// store float with 32-bit displacement
-void LIR_Assembler::store(FloatRegister value, Register base, int offset, BasicType type, CodeEmitInfo *info) {
-  FloatRegisterImpl::Width w;
-  switch(type) {
-    case T_FLOAT : w = FloatRegisterImpl::S; break;
-    case T_DOUBLE: w = FloatRegisterImpl::D; break;
-    default      : ShouldNotReachHere();
-  }
-
-  if (Assembler::is_simm13(offset)) {
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    if (w == FloatRegisterImpl::D && offset % BytesPerLong != 0) {
-      __ stf(FloatRegisterImpl::S, value->successor(), base, offset + BytesPerWord);
-      __ stf(FloatRegisterImpl::S, value             , base, offset);
-    } else {
-      __ stf(w, value, base, offset);
-    }
-  } else {
-    __ set(offset, O7);
-    if (info != NULL) add_debug_info_for_null_check_here(info);
-    __ stf(w, value, O7, base);
-  }
-}
-
-
-int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool unaligned) {
+int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
   int store_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
-    store_offset = store(from_reg, base, O7, type);
+    store_offset = store(from_reg, base, O7, type, wide);
   } else {
-    if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register());
+    if (type == T_ARRAY || type == T_OBJECT) {
+      __ verify_oop(from_reg->as_register());
+    }
     store_offset = code_offset();
     switch (type) {
       case T_BOOLEAN: // fall through
@@ -934,9 +818,22 @@
         __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes);
 #endif
         break;
-      case T_ADDRESS:// fall through
+      case T_ADDRESS:
+        __ st_ptr(from_reg->as_register(), base, offset);
+        break;
       case T_ARRAY : // fall through
-      case T_OBJECT: __ st_ptr(from_reg->as_register(), base, offset); break;
+      case T_OBJECT:
+        {
+          if (UseCompressedOops && !wide) {
+            __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+            store_offset = code_offset();
+            __ stw(G3_scratch, base, offset);
+          } else {
+            __ st_ptr(from_reg->as_register(), base, offset);
+          }
+          break;
+        }
+
       case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break;
       case T_DOUBLE:
         {
@@ -958,8 +855,10 @@
 }
 
 
-int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type) {
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(from_reg->as_register());
+int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) {
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(from_reg->as_register());
+  }
   int store_offset = code_offset();
   switch (type) {
     case T_BOOLEAN: // fall through
@@ -975,9 +874,21 @@
       __ std(from_reg->as_register_hi(), base, disp);
 #endif
       break;
-    case T_ADDRESS:// fall through
+    case T_ADDRESS:
+      __ st_ptr(from_reg->as_register(), base, disp);
+      break;
     case T_ARRAY : // fall through
-    case T_OBJECT: __ st_ptr(from_reg->as_register(), base, disp); break;
+    case T_OBJECT:
+      {
+        if (UseCompressedOops && !wide) {
+          __ encode_heap_oop(from_reg->as_register(), G3_scratch);
+          store_offset = code_offset();
+          __ stw(G3_scratch, base, disp);
+        } else {
+          __ st_ptr(from_reg->as_register(), base, disp);
+        }
+        break;
+      }
     case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break;
     case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break;
     default      : ShouldNotReachHere();
@@ -986,14 +897,14 @@
 }
 
 
-int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool unaligned) {
+int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) {
   int load_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
     assert(base != O7, "destroying register");
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
-    load_offset = load(base, O7, to_reg, type);
+    load_offset = load(base, O7, to_reg, type, wide);
   } else {
     load_offset = code_offset();
     switch(type) {
@@ -1030,9 +941,18 @@
 #endif
         }
         break;
-      case T_ADDRESS:// fall through
+      case T_ADDRESS:  __ ld_ptr(base, offset, to_reg->as_register()); break;
       case T_ARRAY : // fall through
-      case T_OBJECT: __ ld_ptr(base, offset, to_reg->as_register()); break;
+      case T_OBJECT:
+        {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, offset, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ ld_ptr(base, offset, to_reg->as_register());
+          }
+          break;
+        }
       case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break;
       case T_DOUBLE:
         {
@@ -1048,23 +968,34 @@
         }
       default      : ShouldNotReachHere();
     }
-    if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register());
+    if (type == T_ARRAY || type == T_OBJECT) {
+      __ verify_oop(to_reg->as_register());
+    }
   }
   return load_offset;
 }
 
 
-int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type) {
+int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) {
   int load_offset = code_offset();
   switch(type) {
     case T_BOOLEAN: // fall through
-    case T_BYTE  : __ ldsb(base, disp, to_reg->as_register()); break;
-    case T_CHAR  : __ lduh(base, disp, to_reg->as_register()); break;
-    case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break;
-    case T_INT   : __ ld(base, disp, to_reg->as_register()); break;
-    case T_ADDRESS:// fall through
+    case T_BYTE  :  __ ldsb(base, disp, to_reg->as_register()); break;
+    case T_CHAR  :  __ lduh(base, disp, to_reg->as_register()); break;
+    case T_SHORT :  __ ldsh(base, disp, to_reg->as_register()); break;
+    case T_INT   :  __ ld(base, disp, to_reg->as_register()); break;
+    case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break;
     case T_ARRAY : // fall through
-    case T_OBJECT: __ ld_ptr(base, disp, to_reg->as_register()); break;
+    case T_OBJECT:
+      {
+          if (UseCompressedOops && !wide) {
+            __ lduw(base, disp, to_reg->as_register());
+            __ decode_heap_oop(to_reg->as_register());
+          } else {
+            __ ld_ptr(base, disp, to_reg->as_register());
+          }
+          break;
+      }
     case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break;
     case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break;
     case T_LONG  :
@@ -1078,60 +1009,28 @@
       break;
     default      : ShouldNotReachHere();
   }
-  if (type == T_ARRAY || type == T_OBJECT) __ verify_oop(to_reg->as_register());
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(to_reg->as_register());
+  }
   return load_offset;
 }
 
-
-// load/store with an Address
-void LIR_Assembler::load(const Address& a, Register d,  BasicType ld_type, CodeEmitInfo *info, int offset) {
-  load(a.base(), a.disp() + offset, d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(Register value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) {
-  store(value, dest.base(), dest.disp() + offset, type, info);
-}
-
-
-// loadf/storef with an Address
-void LIR_Assembler::load(const Address& a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info, int offset) {
-  load(a.base(), a.disp() + offset, d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(FloatRegister value, const Address& dest, BasicType type, CodeEmitInfo *info, int offset) {
-  store(value, dest.base(), dest.disp() + offset, type, info);
-}
-
-
-// load/store with an Address
-void LIR_Assembler::load(LIR_Address* a, Register d,  BasicType ld_type, CodeEmitInfo *info) {
-  load(as_Address(a), d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(Register value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) {
-  store(value, as_Address(dest), type, info);
-}
-
-
-// loadf/storef with an Address
-void LIR_Assembler::load(LIR_Address* a, FloatRegister d, BasicType ld_type, CodeEmitInfo *info) {
-  load(as_Address(a), d, ld_type, info);
-}
-
-
-void LIR_Assembler::store(FloatRegister value, LIR_Address* dest, BasicType type, CodeEmitInfo *info) {
-  store(value, as_Address(dest), type, info);
-}
-
-
 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
   LIR_Const* c = src->as_constant_ptr();
   switch (c->type()) {
     case T_INT:
-    case T_FLOAT:
+    case T_FLOAT: {
+      Register src_reg = O7;
+      int value = c->as_jint_bits();
+      if (value == 0) {
+        src_reg = G0;
+      } else {
+        __ set(value, O7);
+      }
+      Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
+      __ stw(src_reg, addr.base(), addr.disp());
+      break;
+    }
     case T_ADDRESS: {
       Register src_reg = O7;
       int value = c->as_jint_bits();
@@ -1141,7 +1040,7 @@
         __ set(value, O7);
       }
       Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
-      __ stw(src_reg, addr.base(), addr.disp());
+      __ st_ptr(src_reg, addr.base(), addr.disp());
       break;
     }
     case T_OBJECT: {
@@ -1178,14 +1077,12 @@
 }
 
 
-void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) {
+void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
   LIR_Const* c = src->as_constant_ptr();
   LIR_Address* addr     = dest->as_address_ptr();
   Register base = addr->base()->as_pointer_register();
-
-  if (info != NULL) {
-    add_debug_info_for_null_check_here(info);
-  }
+  int offset = -1;
+
   switch (c->type()) {
     case T_INT:
     case T_FLOAT:
@@ -1199,10 +1096,10 @@
       }
       if (addr->index()->is_valid()) {
         assert(addr->disp() == 0, "must be zero");
-        store(tmp, base, addr->index()->as_pointer_register(), type);
+        offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
       } else {
         assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
-        store(tmp, base, addr->disp(), type);
+        offset = store(tmp, base, addr->disp(), type, wide, false);
       }
       break;
     }
@@ -1212,21 +1109,21 @@
       assert(Assembler::is_simm13(addr->disp()) &&
              Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses");
 
-      Register tmp = O7;
+      LIR_Opr tmp = FrameMap::O7_opr;
       int value_lo = c->as_jint_lo_bits();
       if (value_lo == 0) {
-        tmp = G0;
+        tmp = FrameMap::G0_opr;
       } else {
         __ set(value_lo, O7);
       }
-      store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT);
+      offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false);
       int value_hi = c->as_jint_hi_bits();
       if (value_hi == 0) {
-        tmp = G0;
+        tmp = FrameMap::G0_opr;
       } else {
         __ set(value_hi, O7);
       }
-      store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT);
+      offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false);
       break;
     }
     case T_OBJECT: {
@@ -1241,10 +1138,10 @@
       // handle either reg+reg or reg+disp address
       if (addr->index()->is_valid()) {
         assert(addr->disp() == 0, "must be zero");
-        store(tmp, base, addr->index()->as_pointer_register(), type);
+        offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
       } else {
         assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
-        store(tmp, base, addr->disp(), type);
+        offset = store(tmp, base, addr->disp(), type, wide, false);
       }
 
       break;
@@ -1252,6 +1149,10 @@
     default:
       Unimplemented();
   }
+  if (info != NULL) {
+    assert(offset != -1, "offset should've been set");
+    add_debug_info_for_null_check(offset, info);
+  }
 }
 
 
@@ -1336,7 +1237,7 @@
           assert(to_reg->is_single_cpu(), "Must be a cpu register.");
 
           __ set(const_addrlit, O7);
-          load(O7, 0, to_reg->as_register(), T_INT);
+          __ ld(O7, 0, to_reg->as_register());
         }
       }
       break;
@@ -1429,7 +1330,7 @@
 
 
 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type,
-                            LIR_PatchCode patch_code, CodeEmitInfo* info, bool unaligned) {
+                            LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) {
 
   LIR_Address* addr = src_opr->as_address_ptr();
   LIR_Opr to_reg = dest;
@@ -1475,16 +1376,15 @@
 
   assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
   if (disp_reg == noreg) {
-    offset = load(src, disp_value, to_reg, type, unaligned);
+    offset = load(src, disp_value, to_reg, type, wide, unaligned);
   } else {
     assert(!unaligned, "can't handle this");
-    offset = load(src, disp_reg, to_reg, type);
+    offset = load(src, disp_reg, to_reg, type, wide);
   }
 
   if (patch != NULL) {
     patching_epilog(patch, patch_code, src, info);
   }
-
   if (info != NULL) add_debug_info_for_null_check(offset, info);
 }
 
@@ -1518,7 +1418,7 @@
   }
 
   bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
-  load(addr.base(), addr.disp(), dest, dest->type(), unaligned);
+  load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned);
 }
 
 
@@ -1530,7 +1430,7 @@
     addr = frame_map()->address_for_slot(dest->double_stack_ix());
   }
   bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
-  store(from_reg, addr.base(), addr.disp(), from_reg->type(), unaligned);
+  store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned);
 }
 
 
@@ -1578,7 +1478,7 @@
 
 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type,
                             LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack,
-                            bool unaligned) {
+                            bool wide, bool unaligned) {
   LIR_Address* addr = dest->as_address_ptr();
 
   Register src = addr->base()->as_pointer_register();
@@ -1622,10 +1522,10 @@
 
   assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
   if (disp_reg == noreg) {
-    offset = store(from_reg, src, disp_value, type, unaligned);
+    offset = store(from_reg, src, disp_value, type, wide, unaligned);
   } else {
     assert(!unaligned, "can't handle this");
-    offset = store(from_reg, src, disp_reg, type);
+    offset = store(from_reg, src, disp_reg, type, wide);
   }
 
   if (patch != NULL) {
@@ -2184,13 +2084,13 @@
   // make sure src and dst are non-null and load array length
   if (flags & LIR_OpArrayCopy::src_null_check) {
     __ tst(src);
-    __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
+    __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
     __ delayed()->nop();
   }
 
   if (flags & LIR_OpArrayCopy::dst_null_check) {
     __ tst(dst);
-    __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
+    __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
     __ delayed()->nop();
   }
 
@@ -2232,10 +2132,18 @@
   }
 
   if (flags & LIR_OpArrayCopy::type_check) {
-    __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
-    __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-    __ cmp(tmp, tmp2);
-    __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    if (UseCompressedOops) {
+      // We don't need decode because we just need to compare
+      __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
+      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      __ cmp(tmp, tmp2);
+      __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    } else {
+      __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      __ cmp(tmp, tmp2);
+      __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
+    }
     __ delayed()->nop();
   }
 
@@ -2250,20 +2158,44 @@
     // but not necessarily exactly of type default_type.
     Label known_ok, halt;
     jobject2reg(op->expected_type()->constant_encoding(), tmp);
-    __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
-    if (basic_type != T_OBJECT) {
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::notEqual, false, Assembler::pn, halt);
-      __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+    if (UseCompressedOops) {
+      // tmp holds the default type. It currently comes uncompressed after the
+      // load of a constant, so encode it.
+      __ encode_heap_oop(tmp);
+      // load the raw value of the dst klass, since we will be comparing
+      // uncompressed values directly.
+      __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::notEqual, false, Assembler::pn, halt);
+        // load the raw value of the src klass.
+        __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ br(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     } else {
-      __ cmp(tmp, tmp2);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->cmp(src, dst);
-      __ br(Assembler::equal, false, Assembler::pn, known_ok);
-      __ delayed()->nop();
+      __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
+      if (basic_type != T_OBJECT) {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::notEqual, false, Assembler::pn, halt);
+        __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      } else {
+        __ cmp(tmp, tmp2);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->cmp(src, dst);
+        __ brx(Assembler::equal, false, Assembler::pn, known_ok);
+        __ delayed()->nop();
+      }
     }
     __ bind(halt);
     __ stop("incorrect type information in arraycopy");
@@ -2471,7 +2403,7 @@
     Label next_test;
     Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
                       mdo_offset_bias);
-    load(recv_addr, tmp1, T_OBJECT);
+    __ ld_ptr(recv_addr, tmp1);
     __ br_notnull(tmp1, false, Assembler::pt, next_test);
     __ delayed()->nop();
     __ st_ptr(recv, recv_addr);
@@ -2563,7 +2495,7 @@
 
   // get object class
   // not a safepoint as obj null check happens earlier
-  load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
+  __ load_klass(obj, klass_RInfo);
   if (op->fast_check()) {
     assert_different_registers(klass_RInfo, k_RInfo);
     __ cmp(k_RInfo, klass_RInfo);
@@ -2605,7 +2537,7 @@
       __ set(mdo_offset_bias, tmp1);
       __ add(mdo, tmp1, mdo);
     }
-    load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+    __ load_klass(obj, recv);
     type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
     // Jump over the failure case
     __ ba(false, *success);
@@ -2674,11 +2606,12 @@
       __ br_null(value, false, Assembler::pn, done);
       __ delayed()->nop();
     }
-    load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception());
-    load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
+    add_debug_info_for_null_check_here(op->info_for_exception());
+    __ load_klass(array, k_RInfo);
+    __ load_klass(value, klass_RInfo);
 
     // get instance klass
-    load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL);
+    __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo);
     // perform the fast part of the checking logic
     __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL);
 
@@ -2700,7 +2633,7 @@
         __ set(mdo_offset_bias, tmp1);
         __ add(mdo, tmp1, mdo);
       }
-      load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+      __ load_klass(value, recv);
       type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
       __ ba(false, done);
       __ delayed()->nop();
@@ -2781,14 +2714,17 @@
     Register t2 = op->tmp2()->as_register();
     __ mov(cmp_value, t1);
     __ mov(new_value, t2);
-#ifdef _LP64
     if (op->code() == lir_cas_obj) {
-      __ casx(addr, t1, t2);
-    } else
-#endif
-      {
+      if (UseCompressedOops) {
+        __ encode_heap_oop(t1);
+        __ encode_heap_oop(t2);
         __ cas(addr, t1, t2);
+      } else {
+        __ casx(addr, t1, t2);
       }
+    } else {
+      __ cas(addr, t1, t2);
+    }
     __ cmp(t1, t2);
   } else {
     Unimplemented();
@@ -2966,7 +2902,7 @@
         }
       }
     } else {
-      load(Address(recv, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
+      __ load_klass(recv, recv);
       Label update_done;
       type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done);
       // Receiver did not match any saved receiver and there is no empty row for it.
@@ -3160,7 +3096,7 @@
   } else {
     // use normal move for all other volatiles since they don't need
     // special handling to remain atomic.
-    move_op(src, dest, type, lir_patch_none, info, false, false);
+    move_op(src, dest, type, lir_patch_none, info, false, false, false);
   }
 }