< prev index next >

src/cpu/sparc/vm/macroAssembler_sparc.cpp

Print this page




4499     subcc(limit2, stride2, chr2);
4500   }
4501   subcc(limit1, stride1, chr1);
4502   br(Assembler::zero, true, Assembler::pn, Ldone);
4503   // result is difference in lengths
4504   if (ae == StrIntrinsicNode::UU) {
4505     delayed()->sra(diff, 1, result);  // Divide by 2 to get number of chars
4506   } else {
4507     delayed()->mov(diff, result);
4508   }
4509 
4510   // Shift str1 and str2 to the end of the arrays, negate limit
4511   add(str1, limit1, str1);
4512   add(str2, limit2, str2);
4513   neg(chr1, limit1);  // limit1 = -(limit1-stride1)
4514   if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
4515     neg(chr2, limit2);  // limit2 = -(limit2-stride2)
4516   }
4517 
4518   // Compare the rest of the characters
4519   if (ae == StrIntrinsicNode::UU) {
4520     lduh(str1, limit1, chr1);
4521   } else {
4522     ldub(str1, limit1, chr1);
4523   }
4524 
4525   bind(Lloop);
4526   if (ae == StrIntrinsicNode::LL) {
4527     ldub(str2, limit2, chr2);
4528   } else {
4529     lduh(str2, limit2, chr2);
4530   }
4531 
4532   subcc(chr1, chr2, chr1);
4533   br(Assembler::notZero, false, Assembler::pt, Ldone);
4534   assert(chr1 == result, "result must be pre-placed");
4535   delayed()->inccc(limit1, stride1);
4536   if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
4537     inccc(limit2, stride2);
4538   }
4539 
4540   // annul LDUB if branch is not taken to prevent access past end of string
4541   br(Assembler::notZero, true, Assembler::pt, Lloop);
4542   if (ae == StrIntrinsicNode::UU) {
4543     delayed()->lduh(str1, limit2, chr1);
4544   } else {
4545     delayed()->ldub(str1, limit1, chr1);
4546   }
4547 
4548   // If strings are equal up to min length, return the length difference.
4549   if (ae == StrIntrinsicNode::UU) {
4550     // Divide by 2 to get number of chars
4551     sra(diff, 1, result);
4552   } else {
4553     mov(diff, result);
4554   }
4555 
4556   // Otherwise, return the difference between the first mismatched chars.
4557   bind(Ldone);
4558   if(ae == StrIntrinsicNode::UL) {
4559     // Negate result (see note above)
4560     neg(result);
4561   }
4562 }
4563 
4564 void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary2,
4565                                   Register limit, Register tmp, Register result, bool is_byte) {
4566   Label Ldone, Lvector, Lloop;
4567   assert_different_registers(ary1, ary2, limit, tmp, result);
4568 
4569   int length_offset  = arrayOopDesc::length_offset_in_bytes();
4570   int base_offset    = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR);
4571 
4572   if (is_array_equ) {
4573     // return true if the same array
4574     cmp(ary1, ary2);
4575     brx(Assembler::equal, true, Assembler::pn, Ldone);
4576     delayed()->add(G0, 1, result); // equal
4577 
4578     br_null(ary1, true, Assembler::pn, Ldone);
4579     delayed()->mov(G0, result);    // not equal
4580 
4581     br_null(ary2, true, Assembler::pn, Ldone);
4582     delayed()->mov(G0, result);    // not equal
4583 
4584     // load the lengths of arrays
4585     ld(Address(ary1, length_offset), limit);
4586     ld(Address(ary2, length_offset), tmp);
4587 
4588     // return false if the two arrays are not equal length
4589     cmp(limit, tmp);
4590     br(Assembler::notEqual, true, Assembler::pn, Ldone);
4591     delayed()->mov(G0, result);    // not equal
4592   }
4593 
4594   cmp_zero_and_br(Assembler::zero, limit, Ldone, true, Assembler::pn);
4595   delayed()->add(G0, 1, result); // zero-length arrays are equal
4596 
4597   if (is_array_equ) {
4598     // load array addresses
4599     add(ary1, base_offset, ary1);
4600     add(ary2, base_offset, ary2);




4601   } else {
4602     // We have no guarantee that on 64 bit the higher half of limit is 0
4603     signx(limit);
4604   }
4605 
4606   if (is_byte) {
4607     Label Lskip;
4608     // check for trailing byte
4609     andcc(limit, 0x1, tmp);
4610     br(Assembler::zero, false, Assembler::pt, Lskip);
4611     delayed()->nop();
4612 
4613     // compare the trailing byte
4614     sub(limit, sizeof(jbyte), limit);
4615     ldub(ary1, limit, result);
4616     ldub(ary2, limit, tmp);
4617     cmp(result, tmp);
4618     br(Assembler::notEqual, true, Assembler::pt, Ldone);
4619     delayed()->mov(G0, result);    // not equal
4620 
4621     // only one byte?
4622     cmp_zero_and_br(zero, limit, Ldone, true, Assembler::pn);
4623     delayed()->add(G0, 1, result); // zero-length arrays are equal
4624     bind(Lskip);
4625   } else if (is_array_equ) {
4626     // set byte count
4627     sll(limit, exact_log2(sizeof(jchar)), limit);
4628   }
4629 
4630   // check for trailing character
4631   andcc(limit, 0x2, tmp);
4632   br(Assembler::zero, false, Assembler::pt, Lvector);
4633   delayed()->nop();
4634 
4635   // compare the trailing char
4636   sub(limit, sizeof(jchar), limit);
4637   lduh(ary1, limit, result);
4638   lduh(ary2, limit, tmp);
4639   cmp(result, tmp);
4640   br(Assembler::notEqual, true, Assembler::pt, Ldone);
4641   delayed()->mov(G0, result);     // not equal
4642 
4643   // only one char?
4644   cmp_zero_and_br(zero, limit, Ldone, true, Assembler::pn);
4645   delayed()->add(G0, 1, result); // zero-length arrays are equal



4646 
4647   // word by word compare, dont't need alignment check
4648   bind(Lvector);
4649   // Shift ary1 and ary2 to the end of the arrays, negate limit
4650   add(ary1, limit, ary1);
4651   add(ary2, limit, ary2);
4652   neg(limit, limit);
4653 
4654   lduw(ary1, limit, result);





4655   bind(Lloop);
4656   lduw(ary2, limit, tmp);























4657   cmp(result, tmp);
4658   br(Assembler::notEqual, true, Assembler::pt, Ldone);
4659   delayed()->mov(G0, result);     // not equal
4660   inccc(limit, 2*sizeof(jchar));
4661   // annul LDUW if branch is not taken to prevent access past end of array
4662   br(Assembler::notZero, true, Assembler::pt, Lloop);
4663   delayed()->lduw(ary1, limit, result); // hoisted
4664 
4665   add(G0, 1, result); // equals
4666   bind(Ldone);
4667 }
4668 
4669 void MacroAssembler::has_negatives(Register inp, Register size, Register result, Register t2, Register t3, Register t4, Register t5) {
4670 
4671   // test for negative bytes in input string of a given size
4672   // result 1 if found, 0 otherwise.
4673 
4674   Label Lcore, Ltail, Lreturn, Lcore_rpt;
4675 
4676   assert_different_registers(inp, size, t2, t3, t4, t5, result);
4677 
4678   Register i     = result;  // result used as integer index i until very end
4679   Register lmask = t2;      // t2 is aliased to lmask
4680 
4681   // INITIALIZATION
4682   // ===========================================================
4683   // initialize highbits mask -> lmask = 0x8080808080808080  (8B/64b)
4684   // compute unaligned offset -> i
4685   // compute core end index   -> t5
4686   Assembler::sethi(0x80808000, t2);   //! sethi macro fails to emit optimal




4499     subcc(limit2, stride2, chr2);
4500   }
4501   subcc(limit1, stride1, chr1);
4502   br(Assembler::zero, true, Assembler::pn, Ldone);
4503   // result is difference in lengths
4504   if (ae == StrIntrinsicNode::UU) {
4505     delayed()->sra(diff, 1, result);  // Divide by 2 to get number of chars
4506   } else {
4507     delayed()->mov(diff, result);
4508   }
4509 
4510   // Shift str1 and str2 to the end of the arrays, negate limit
4511   add(str1, limit1, str1);
4512   add(str2, limit2, str2);
4513   neg(chr1, limit1);  // limit1 = -(limit1-stride1)
4514   if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
4515     neg(chr2, limit2);  // limit2 = -(limit2-stride2)
4516   }
4517 
4518   // Compare the rest of the characters
4519   load_sized_value(Address(str1, limit1), chr1, (ae == StrIntrinsicNode::UU) ? 2 : 1, false);




4520 
4521   bind(Lloop);
4522   load_sized_value(Address(str2, limit2), chr2, (ae == StrIntrinsicNode::LL) ? 1 : 2, false);




4523 
4524   subcc(chr1, chr2, chr1);
4525   br(Assembler::notZero, false, Assembler::pt, Ldone);
4526   assert(chr1 == result, "result must be pre-placed");
4527   delayed()->inccc(limit1, stride1);
4528   if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
4529     inccc(limit2, stride2);
4530   }
4531 
4532   // annul LDUB if branch is not taken to prevent access past end of string
4533   br(Assembler::notZero, true, Assembler::pt, Lloop);
4534   delayed()->load_sized_value(Address(str1, limit1), chr1, (ae == StrIntrinsicNode::UU) ? 2 : 1, false);




4535 
4536   // If strings are equal up to min length, return the length difference.
4537   if (ae == StrIntrinsicNode::UU) {
4538     // Divide by 2 to get number of chars
4539     sra(diff, 1, result);
4540   } else {
4541     mov(diff, result);
4542   }
4543 
4544   // Otherwise, return the difference between the first mismatched chars.
4545   bind(Ldone);
4546   if(ae == StrIntrinsicNode::UL) {
4547     // Negate result (see note above)
4548     neg(result);
4549   }
4550 }
4551 
4552 void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary2,
4553                                   Register limit, Register tmp, Register result, bool is_byte) {
4554   Label Ldone, Lslow;
4555   assert_different_registers(ary1, ary2, limit, tmp, result);
4556 
4557   int length_offset  = arrayOopDesc::length_offset_in_bytes();
4558   int base_offset    = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR);
4559 
4560   if (is_array_equ) {
4561     // return true if the same array
4562     cmp(ary1, ary2);
4563     brx(Assembler::equal, true, Assembler::pn, Ldone);
4564     delayed()->mov(1, result);  // equal
4565 
4566     br_null(ary1, true, Assembler::pn, Ldone);
4567     delayed()->clr(result);     // not equal
4568 
4569     br_null(ary2, true, Assembler::pn, Ldone);
4570     delayed()->clr(result);     // not equal
4571 
4572     // load the lengths of arrays
4573     ld(Address(ary1, length_offset), limit);
4574     ld(Address(ary2, length_offset), tmp);
4575 
4576     // return false if the two arrays are not equal length
4577     cmp(limit, tmp);
4578     br(Assembler::notEqual, true, Assembler::pn, Ldone);
4579     delayed()->clr(result);     // not equal
4580   }
4581 
4582   cmp_zero_and_br(Assembler::zero, limit, Ldone, true, Assembler::pn);
4583   delayed()->mov(1, result); // zero-length arrays are equal
4584 
4585   if (is_array_equ) {
4586     // load array addresses
4587     add(ary1, base_offset, ary1);
4588     add(ary2, base_offset, ary2);
4589     // set byte count
4590     if (!is_byte) {
4591       sll(limit, exact_log2(sizeof(jchar)), limit);
4592     }
4593   } else {
4594     // We have no guarantee that on 64 bit the higher half of limit is 0
4595     signx(limit);
4596   }
4597 
4598   // Prefetch beginning of arrays
4599   prefetch(ary1, 0, Assembler::severalReads);
4600   prefetch(ary2, 0, Assembler::severalReads);
4601 
4602   // Check for doubleword (8 byte) alignment of ary1 and ary2
4603   or3(ary1, ary2, tmp);
4604   andcc(tmp, 7, tmp);
4605   br_notnull_short(tmp, Assembler::pn, Lslow);
4606 
4607   // Aligned, perform doubleword comparison
4608   array_equals_loop(ary1, ary2, limit, tmp, result, 8, Ldone);
4609   ba(Ldone);
4610   delayed()->movcc(Assembler::equal, false, xcc, 1, result);
4611 
4612   bind(Lslow);
4613   // Unaligned, perform word comparison (word alignment is guaranteed)
4614   array_equals_loop(ary1, ary2, limit, tmp, result, 4, Ldone);
4615   movcc(Assembler::equal, false, icc, 1, result);





4616 
4617   bind(Ldone);
4618 }










4619 
4620 // Compares two arrays in chunks of size 'byte_width'. The addresses must be aligned accordingly.
4621 void MacroAssembler::array_equals_loop(Register ary1, Register ary2, Register limit, Register tmp,
4622                                        Register result, size_t byte_width, Label& Ldone) {
4623   Label Lloop, Lremaining;
4624   // Use appropriate CC register depending on byte_width
4625   Assembler::CC cc = (byte_width == 8) ? xcc : icc;
4626 


4627   // Shift ary1 and ary2 to the end of the arrays, negate limit
4628   add(ary1, limit, ary1);
4629   add(ary2, limit, ary2);
4630   neg(limit, limit);
4631 
4632   // MAIN LOOP
4633   // Load and compare array elements of size 'byte_width' until the elements are not
4634   // equal or we reached the end of the arrays. If the size of the arrays is not a
4635   // multiple of 'byte_width', we simply read over the end of the array, bail out and
4636   // compare the remaining bytes below by skipping the garbage bytes.
4637   load_sized_value(Address(ary1, limit), result, byte_width, false);
4638   bind(Lloop);
4639   load_sized_value(Address(ary2, limit), tmp, byte_width, false);
4640   inccc(limit, byte_width);
4641   // Bail out if we reached the end (but still do the comparison)
4642   br(Assembler::positive, false, Assembler::pn, Lremaining);
4643   delayed()->cmp(result, tmp);
4644   // Check equality of elements
4645   bp(Assembler::equal, false, cc, Assembler::pt, target(Lloop));
4646   delayed()->load_sized_value(Address(ary1, limit), result, byte_width, false);
4647 
4648   ba(Ldone);
4649   delayed()->clr(result); // not equal
4650 
4651   // TAIL COMPARISON
4652   // We got here because we reached the end of the arrays. 'limit' is the number of
4653   // garbage bytes we may have compared by reading over the end of the arrays. Shift
4654   // out the garbage and compare the remaining elements.
4655   bind(Lremaining);
4656   // Optimistic shortcut: elements potentially including garbage are equal
4657   bp(Assembler::equal, true, cc, Assembler::pt, target(Ldone));
4658   delayed()->mov(1, result); // equal
4659   // Shift 'limit' bytes to the right and compare
4660   sll(limit, 3, limit); // bytes to bits
4661   srlx(result, limit, result);
4662   srlx(tmp, limit, tmp);
4663   cmp(result, tmp);
4664   clr(result);
4665   // CC register contains result







4666 }
4667 
4668 void MacroAssembler::has_negatives(Register inp, Register size, Register result, Register t2, Register t3, Register t4, Register t5) {
4669 
4670   // test for negative bytes in input string of a given size
4671   // result 1 if found, 0 otherwise.
4672 
4673   Label Lcore, Ltail, Lreturn, Lcore_rpt;
4674 
4675   assert_different_registers(inp, size, t2, t3, t4, t5, result);
4676 
4677   Register i     = result;  // result used as integer index i until very end
4678   Register lmask = t2;      // t2 is aliased to lmask
4679 
4680   // INITIALIZATION
4681   // ===========================================================
4682   // initialize highbits mask -> lmask = 0x8080808080808080  (8B/64b)
4683   // compute unaligned offset -> i
4684   // compute core end index   -> t5
4685   Assembler::sethi(0x80808000, t2);   //! sethi macro fails to emit optimal


< prev index next >