src/hotspot/cpu/ppc/templateTable_ppc_64.cpp
changeset 48965 be873d8c0114
parent 48608 1dab70e20292
child 49164 7e958a8ebcd3
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Tue Feb 13 16:57:01 2018 +0100
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp	Tue Feb 13 17:38:03 2018 +0100
@@ -314,7 +314,7 @@
            Rcpool    = R3_ARG1;
 
   transition(vtos, vtos);
-  Label notInt, notClass, exit;
+  Label notInt, notFloat, notClass, exit;
 
   __ get_cpool_and_tags(Rcpool, Rscratch2); // Set Rscratch2 = &tags.
   if (wide) { // Read index.
@@ -356,13 +356,16 @@
 
   __ align(32, 12);
   __ bind(notInt);
-#ifdef ASSERT
-  // String and Object are rewritten to fast_aldc
   __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float);
-  __ asm_assert_eq("unexpected type", 0x8765);
-#endif
+  __ bne(CCR0, notFloat);
   __ lfsx(F15_ftos, Rcpool, Rscratch1);
   __ push(ftos);
+  __ b(exit);
+
+  __ align(32, 12);
+  // assume the tag is for condy; if not, the VM runtime will tell us
+  __ bind(notFloat);
+  condy_helper(exit);
 
   __ align(32, 12);
   __ bind(exit);
@@ -380,6 +383,19 @@
   // non-null object (CallSite, etc.)
   __ get_cache_index_at_bcp(Rscratch, 1, index_size);  // Load index.
   __ load_resolved_reference_at_index(R17_tos, Rscratch, &is_null);
+
+  // Convert null sentinel to NULL.
+  int simm16_rest = __ load_const_optimized(Rscratch, Universe::the_null_sentinel_addr(), R0, true);
+  __ ld(Rscratch, simm16_rest, Rscratch);
+  __ cmpld(CCR0, R17_tos, Rscratch);
+  if (VM_Version::has_isel()) {
+    __ isel_0(R17_tos, CCR0, Assembler::equal);
+  } else {
+    Label not_sentinel;
+    __ bne(CCR0, not_sentinel);
+    __ li(R17_tos, 0);
+    __ bind(not_sentinel);
+  }
   __ verify_oop(R17_tos);
   __ dispatch_epilog(atos, Bytecodes::length_for(bytecode()));
 
@@ -395,7 +411,7 @@
 
 void TemplateTable::ldc2_w() {
   transition(vtos, vtos);
-  Label Llong, Lexit;
+  Label not_double, not_long, exit;
 
   Register Rindex = R11_scratch1,
            Rcpool = R12_scratch2,
@@ -410,23 +426,129 @@
   __ addi(Rtag, Rtag, tags_offset);
 
   __ lbzx(Rtag, Rtag, Rindex);
-
   __ sldi(Rindex, Rindex, LogBytesPerWord);
+
   __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Double);
-  __ bne(CCR0, Llong);
-  // A double can be placed at word-aligned locations in the constant pool.
-  // Check out Conversions.java for an example.
-  // Also ConstantPool::header_size() is 20, which makes it very difficult
-  // to double-align double on the constant pool. SG, 11/7/97
+  __ bne(CCR0, not_double);
   __ lfdx(F15_ftos, Rcpool, Rindex);
   __ push(dtos);
-  __ b(Lexit);
-
-  __ bind(Llong);
+  __ b(exit);
+
+  __ bind(not_double);
+  __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Long);
+  __ bne(CCR0, not_long);
   __ ldx(R17_tos, Rcpool, Rindex);
   __ push(ltos);
-
-  __ bind(Lexit);
+  __ b(exit);
+
+  __ bind(not_long);
+  condy_helper(exit);
+
+  __ align(32, 12);
+  __ bind(exit);
+}
+
+void TemplateTable::condy_helper(Label& Done) {
+  const Register obj   = R31;
+  const Register off   = R11_scratch1;
+  const Register flags = R12_scratch2;
+  const Register rarg  = R4_ARG2;
+  __ li(rarg, (int)bytecode());
+  call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg);
+  __ get_vm_result_2(flags);
+
+  // VMr = obj = base address to find primitive value to push
+  // VMr2 = flags = (tos, off) using format of CPCE::_flags
+  __ andi(off, flags, ConstantPoolCacheEntry::field_index_mask);
+
+  // What sort of thing are we loading?
+  __ rldicl(flags, flags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+
+  switch (bytecode()) {
+  case Bytecodes::_ldc:
+  case Bytecodes::_ldc_w:
+    {
+      // tos in (itos, ftos, stos, btos, ctos, ztos)
+      Label notInt, notFloat, notShort, notByte, notChar, notBool;
+      __ cmplwi(CCR0, flags, itos);
+      __ bne(CCR0, notInt);
+      // itos
+      __ lwax(R17_tos, obj, off);
+      __ push(itos);
+      __ b(Done);
+
+      __ bind(notInt);
+      __ cmplwi(CCR0, flags, ftos);
+      __ bne(CCR0, notFloat);
+      // ftos
+      __ lfsx(F15_ftos, obj, off);
+      __ push(ftos);
+      __ b(Done);
+
+      __ bind(notFloat);
+      __ cmplwi(CCR0, flags, stos);
+      __ bne(CCR0, notShort);
+      // stos
+      __ lhax(R17_tos, obj, off);
+      __ push(stos);
+      __ b(Done);
+
+      __ bind(notShort);
+      __ cmplwi(CCR0, flags, btos);
+      __ bne(CCR0, notByte);
+      // btos
+      __ lbzx(R17_tos, obj, off);
+      __ extsb(R17_tos, R17_tos);
+      __ push(btos);
+      __ b(Done);
+
+      __ bind(notByte);
+      __ cmplwi(CCR0, flags, ctos);
+      __ bne(CCR0, notChar);
+      // ctos
+      __ lhzx(R17_tos, obj, off);
+      __ push(ctos);
+      __ b(Done);
+
+      __ bind(notChar);
+      __ cmplwi(CCR0, flags, ztos);
+      __ bne(CCR0, notBool);
+      // ztos
+      __ lbzx(R17_tos, obj, off);
+      __ push(ztos);
+      __ b(Done);
+
+      __ bind(notBool);
+      break;
+    }
+
+  case Bytecodes::_ldc2_w:
+    {
+      Label notLong, notDouble;
+      __ cmplwi(CCR0, flags, ltos);
+      __ bne(CCR0, notLong);
+      // ltos
+      __ ldx(R17_tos, obj, off);
+      __ push(ltos);
+      __ b(Done);
+
+      __ bind(notLong);
+      __ cmplwi(CCR0, flags, dtos);
+      __ bne(CCR0, notDouble);
+      // dtos
+      __ lfdx(F15_ftos, obj, off);
+      __ push(dtos);
+      __ b(Done);
+
+      __ bind(notDouble);
+      break;
+    }
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  __ stop("bad ldc/condy");
 }
 
 // Get the locals index located in the bytecode stream at bcp + offset.