1608 // returns the (pc) offset of the div instruction - may be needed
1609 // for implicit exceptions.
1610 //
1611 // constraint : ra/rb =/= scratch
1612 // normal case
1613 //
1614 // input : ra: dividend
1615 // rb: divisor
1616 //
1617 // result: either
1618 // quotient (= ra idiv rb)
1619 // remainder (= ra irem rb)
1620
1621 assert(ra != scratch && rb != scratch, "reg cannot be scratch");
1622
1623 int idivl_offset = offset();
1624 if (! want_remainder) {
1625 sdivw(result, ra, rb);
1626 } else {
1627 sdivw(scratch, ra, rb);
1628 msubw(result, scratch, rb, ra);
1629 }
1630
1631 return idivl_offset;
1632 }
1633
1634 int MacroAssembler::corrected_idivq(Register result, Register ra, Register rb,
1635 bool want_remainder, Register scratch)
1636 {
1637 // Full implementation of Java ldiv and lrem. The function
1638 // returns the (pc) offset of the div instruction - may be needed
1639 // for implicit exceptions.
1640 //
1641 // constraint : ra/rb =/= scratch
1642 // normal case
1643 //
1644 // input : ra: dividend
1645 // rb: divisor
1646 //
1647 // result: either
1648 // quotient (= ra idiv rb)
1649 // remainder (= ra irem rb)
1650
1651 assert(ra != scratch && rb != scratch, "reg cannot be scratch");
1652
1653 int idivq_offset = offset();
1654 if (! want_remainder) {
1655 sdiv(result, ra, rb);
1656 } else {
1657 sdiv(scratch, ra, rb);
1658 msub(result, scratch, rb, ra);
1659 }
1660
1661 return idivq_offset;
1662 }
1663
1664 // MacroAssembler routines found actually to be needed
1665
1666 void MacroAssembler::push(Register src)
1667 {
1668 str(src, Address(pre(esp, -1 * wordSize)));
1669 }
1670
1671 void MacroAssembler::pop(Register dst)
1672 {
1673 ldr(dst, Address(post(esp, 1 * wordSize)));
1674 }
1675
1676 // Note: load_unsigned_short used to be called load_unsigned_word.
1677 int MacroAssembler::load_unsigned_short(Register dst, Address src) {
1678 int off = offset();
3434
3435 void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byte_offset) {
3436 relocInfo::relocType rtype = dest.rspec().reloc()->type();
3437 if (uabs(pc() - dest.target()) >= (1LL << 32)) {
3438 guarantee(rtype == relocInfo::none
3439 || rtype == relocInfo::external_word_type
3440 || rtype == relocInfo::poll_type
3441 || rtype == relocInfo::poll_return_type,
3442 "can only use a fixed address with an ADRP");
3443 // Out of range. This doesn't happen very often, but we have to
3444 // handle it
3445 mov(reg1, dest);
3446 byte_offset = 0;
3447 } else {
3448 InstructionMark im(this);
3449 code_section()->relocate(inst_mark(), dest.rspec());
3450 byte_offset = (uint64_t)dest.target() & 0xfff;
3451 _adrp(reg1, dest.target());
3452 }
3453 }
3454
3455 bool MacroAssembler::use_acq_rel_for_volatile_fields() {
3456 #ifdef PRODUCT
3457 return false;
3458 #else
3459 return UseAcqRelForVolatileFields;
3460 #endif
3461 }
3462
3463 void MacroAssembler::build_frame(int framesize) {
3464 if (framesize == 0) {
3465 // Is this even possible?
3466 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
3467 } else if (framesize < ((1 << 9) + 2 * wordSize)) {
3468 sub(sp, sp, framesize);
3469 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
3470 } else {
3471 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
3472 if (framesize < ((1 << 12) + 2 * wordSize))
3473 sub(sp, sp, framesize - 2 * wordSize);
3474 else {
3475 mov(rscratch1, framesize - 2 * wordSize);
3476 sub(sp, sp, rscratch1);
3477 }
3478 }
3479 }
3480
3481 void MacroAssembler::remove_frame(int framesize) {
|
1608 // returns the (pc) offset of the div instruction - may be needed
1609 // for implicit exceptions.
1610 //
1611 // constraint : ra/rb =/= scratch
1612 // normal case
1613 //
1614 // input : ra: dividend
1615 // rb: divisor
1616 //
1617 // result: either
1618 // quotient (= ra idiv rb)
1619 // remainder (= ra irem rb)
1620
1621 assert(ra != scratch && rb != scratch, "reg cannot be scratch");
1622
1623 int idivl_offset = offset();
1624 if (! want_remainder) {
1625 sdivw(result, ra, rb);
1626 } else {
1627 sdivw(scratch, ra, rb);
1628 Assembler::msubw(result, scratch, rb, ra);
1629 }
1630
1631 return idivl_offset;
1632 }
1633
1634 int MacroAssembler::corrected_idivq(Register result, Register ra, Register rb,
1635 bool want_remainder, Register scratch)
1636 {
1637 // Full implementation of Java ldiv and lrem. The function
1638 // returns the (pc) offset of the div instruction - may be needed
1639 // for implicit exceptions.
1640 //
1641 // constraint : ra/rb =/= scratch
1642 // normal case
1643 //
1644 // input : ra: dividend
1645 // rb: divisor
1646 //
1647 // result: either
1648 // quotient (= ra idiv rb)
1649 // remainder (= ra irem rb)
1650
1651 assert(ra != scratch && rb != scratch, "reg cannot be scratch");
1652
1653 int idivq_offset = offset();
1654 if (! want_remainder) {
1655 sdiv(result, ra, rb);
1656 } else {
1657 sdiv(scratch, ra, rb);
1658 Assembler::msub(result, scratch, rb, ra);
1659 }
1660
1661 return idivq_offset;
1662 }
1663
1664 // MacroAssembler routines found actually to be needed
1665
1666 void MacroAssembler::push(Register src)
1667 {
1668 str(src, Address(pre(esp, -1 * wordSize)));
1669 }
1670
1671 void MacroAssembler::pop(Register dst)
1672 {
1673 ldr(dst, Address(post(esp, 1 * wordSize)));
1674 }
1675
1676 // Note: load_unsigned_short used to be called load_unsigned_word.
1677 int MacroAssembler::load_unsigned_short(Register dst, Address src) {
1678 int off = offset();
3434
3435 void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byte_offset) {
3436 relocInfo::relocType rtype = dest.rspec().reloc()->type();
3437 if (uabs(pc() - dest.target()) >= (1LL << 32)) {
3438 guarantee(rtype == relocInfo::none
3439 || rtype == relocInfo::external_word_type
3440 || rtype == relocInfo::poll_type
3441 || rtype == relocInfo::poll_return_type,
3442 "can only use a fixed address with an ADRP");
3443 // Out of range. This doesn't happen very often, but we have to
3444 // handle it
3445 mov(reg1, dest);
3446 byte_offset = 0;
3447 } else {
3448 InstructionMark im(this);
3449 code_section()->relocate(inst_mark(), dest.rspec());
3450 byte_offset = (uint64_t)dest.target() & 0xfff;
3451 _adrp(reg1, dest.target());
3452 }
3453 }
3454
3455 void MacroAssembler::build_frame(int framesize) {
3456 if (framesize == 0) {
3457 // Is this even possible?
3458 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
3459 } else if (framesize < ((1 << 9) + 2 * wordSize)) {
3460 sub(sp, sp, framesize);
3461 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
3462 } else {
3463 stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
3464 if (framesize < ((1 << 12) + 2 * wordSize))
3465 sub(sp, sp, framesize - 2 * wordSize);
3466 else {
3467 mov(rscratch1, framesize - 2 * wordSize);
3468 sub(sp, sp, rscratch1);
3469 }
3470 }
3471 }
3472
3473 void MacroAssembler::remove_frame(int framesize) {
|