hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
changeset 33628 09241459a8b8
parent 30764 fec48bf5a827
child 34205 9ec51d30a11e
equal deleted inserted replaced
33627:c5b7455f846e 33628:09241459a8b8
   227       __ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
   227       __ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
   228       __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
   228       __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
   229       __ st_ptr(O7, frame_map()->address_for_monitor_object(i));
   229       __ st_ptr(O7, frame_map()->address_for_monitor_object(i));
   230     }
   230     }
   231   }
   231   }
   232 }
       
   233 
       
   234 
       
   235 // Optimized Library calls
       
   236 // This is the fast version of java.lang.String.compare; it has not
       
   237 // OSR-entry and therefore, we generate a slow version for OSR's
       
   238 void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) {
       
   239   Register str0 = left->as_register();
       
   240   Register str1 = right->as_register();
       
   241 
       
   242   Label Ldone;
       
   243 
       
   244   Register result = dst->as_register();
       
   245   {
       
   246     // Get a pointer to the first character of string0 in tmp0
       
   247     //   and get string0.length() in str0
       
   248     // Get a pointer to the first character of string1 in tmp1
       
   249     //   and get string1.length() in str1
       
   250     // Also, get string0.length()-string1.length() in
       
   251     //   o7 and get the condition code set
       
   252     // Note: some instructions have been hoisted for better instruction scheduling
       
   253 
       
   254     Register tmp0 = L0;
       
   255     Register tmp1 = L1;
       
   256     Register tmp2 = L2;
       
   257 
       
   258     int  value_offset = java_lang_String:: value_offset_in_bytes(); // char array
       
   259     if (java_lang_String::has_offset_field()) {
       
   260       int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
       
   261       int  count_offset = java_lang_String:: count_offset_in_bytes();
       
   262       __ load_heap_oop(str0, value_offset, tmp0);
       
   263       __ ld(str0, offset_offset, tmp2);
       
   264       __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
       
   265       __ ld(str0, count_offset, str0);
       
   266       __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
       
   267     } else {
       
   268       __ load_heap_oop(str0, value_offset, tmp1);
       
   269       __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
       
   270       __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0);
       
   271     }
       
   272 
       
   273     // str1 may be null
       
   274     add_debug_info_for_null_check_here(info);
       
   275 
       
   276     if (java_lang_String::has_offset_field()) {
       
   277       int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
       
   278       int  count_offset = java_lang_String:: count_offset_in_bytes();
       
   279       __ load_heap_oop(str1, value_offset, tmp1);
       
   280       __ add(tmp0, tmp2, tmp0);
       
   281 
       
   282       __ ld(str1, offset_offset, tmp2);
       
   283       __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
       
   284       __ ld(str1, count_offset, str1);
       
   285       __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
       
   286       __ add(tmp1, tmp2, tmp1);
       
   287     } else {
       
   288       __ load_heap_oop(str1, value_offset, tmp2);
       
   289       __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
       
   290       __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1);
       
   291     }
       
   292     __ subcc(str0, str1, O7);
       
   293   }
       
   294 
       
   295   {
       
   296     // Compute the minimum of the string lengths, scale it and store it in limit
       
   297     Register count0 = I0;
       
   298     Register count1 = I1;
       
   299     Register limit  = L3;
       
   300 
       
   301     Label Lskip;
       
   302     __ sll(count0, exact_log2(sizeof(jchar)), limit);             // string0 is shorter
       
   303     __ br(Assembler::greater, true, Assembler::pt, Lskip);
       
   304     __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit);  // string1 is shorter
       
   305     __ bind(Lskip);
       
   306 
       
   307     // If either string is empty (or both of them) the result is the difference in lengths
       
   308     __ cmp(limit, 0);
       
   309     __ br(Assembler::equal, true, Assembler::pn, Ldone);
       
   310     __ delayed()->mov(O7, result);  // result is difference in lengths
       
   311   }
       
   312 
       
   313   {
       
   314     // Neither string is empty
       
   315     Label Lloop;
       
   316 
       
   317     Register base0 = L0;
       
   318     Register base1 = L1;
       
   319     Register chr0  = I0;
       
   320     Register chr1  = I1;
       
   321     Register limit = L3;
       
   322 
       
   323     // Shift base0 and base1 to the end of the arrays, negate limit
       
   324     __ add(base0, limit, base0);
       
   325     __ add(base1, limit, base1);
       
   326     __ neg(limit);  // limit = -min{string0.length(), string1.length()}
       
   327 
       
   328     __ lduh(base0, limit, chr0);
       
   329     __ bind(Lloop);
       
   330     __ lduh(base1, limit, chr1);
       
   331     __ subcc(chr0, chr1, chr0);
       
   332     __ br(Assembler::notZero, false, Assembler::pn, Ldone);
       
   333     assert(chr0 == result, "result must be pre-placed");
       
   334     __ delayed()->inccc(limit, sizeof(jchar));
       
   335     __ br(Assembler::notZero, true, Assembler::pt, Lloop);
       
   336     __ delayed()->lduh(base0, limit, chr0);
       
   337   }
       
   338 
       
   339   // If strings are equal up to min length, return the length difference.
       
   340   __ mov(O7, result);
       
   341 
       
   342   // Otherwise, return the difference between the first mismatched chars.
       
   343   __ bind(Ldone);
       
   344 }
   232 }
   345 
   233 
   346 
   234 
   347 // --------------------------------------------------------------------------------------------
   235 // --------------------------------------------------------------------------------------------
   348 
   236