14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 #include <stdio.h>
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "asm/assembler.hpp"
30 #include "asm/assembler.inline.hpp"
31 #include "interpreter/interpreter.hpp"
32
33 #ifndef PRODUCT
34 const unsigned long Assembler::asm_bp = 0x00007fffee09ac88;
35 #endif
36
37 #include "compiler/disassembler.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "runtime/interfaceSupport.inline.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #include "immediate_aarch64.hpp"
42
43 extern "C" void entry(CodeBuffer *cb);
44
45 #define __ _masm.
46 #ifdef PRODUCT
47 #define BLOCK_COMMENT(str) /* nothing */
48 #else
49 #define BLOCK_COMMENT(str) block_comment(str)
50 #endif
51
52 #define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":")
53
54 static float unpack(unsigned value);
1476 RelocationHolder const& rspec,
1477 int format) {
1478
1479 assert(inst_mark() != NULL, "must be inside InstructionMark");
1480 // Do not use AbstractAssembler::relocate, which is not intended for
1481 // embedded words. Instead, relocate to the enclosing instruction.
1482 code_section()->relocate(inst_mark(), rspec, format);
1483 emit_int64(data);
1484 }
1485
1486 extern "C" {
1487 void das(uint64_t start, int len) {
1488 ResourceMark rm;
1489 len <<= 2;
1490 if (len < 0)
1491 Disassembler::decode((address)start + len, (address)start);
1492 else
1493 Disassembler::decode((address)start, (address)start + len);
1494 }
1495
1496 JNIEXPORT void das1(unsigned long insn) {
1497 das(insn, 1);
1498 }
1499 }
1500
1501 #define gas_assert(ARG1) assert(ARG1, #ARG1)
1502
1503 #define __ as->
1504
1505 void Address::lea(MacroAssembler *as, Register r) const {
1506 Relocation* reloc = _rspec.reloc();
1507 relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
1508
1509 switch(_mode) {
1510 case base_plus_offset: {
1511 if (_offset == 0 && _base == r) // it's a nop
1512 break;
1513 if (_offset > 0)
1514 __ add(r, _base, _offset);
1515 else
1516 __ sub(r, _base, -_offset);
1517 break;
1518 }
1519 case base_plus_offset_reg: {
1520 __ add(r, _base, _index, _ext.op(), MAX(_ext.shift(), 0));
1521 break;
1522 }
1523 case literal: {
1524 if (rtype == relocInfo::none)
1525 __ mov(r, target());
1526 else
1527 __ movptr(r, (uint64_t)target());
1528 break;
1529 }
1530 default:
1531 ShouldNotReachHere();
1532 }
1533 }
1534
1535 void Assembler::adrp(Register reg1, const Address &dest, unsigned long &byte_offset) {
1536 ShouldNotReachHere();
1537 }
1538
1539 #undef __
1540
1541 #define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use)
1542
1543 void Assembler::adr(Register Rd, address adr) {
1544 long offset = adr - pc();
1545 int offset_lo = offset & 3;
1546 offset >>= 2;
1547 starti;
1548 f(0, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
1549 rf(Rd, 0);
1550 }
1551
1552 void Assembler::_adrp(Register Rd, address adr) {
1553 uint64_t pc_page = (uint64_t)pc() >> 12;
1554 uint64_t adr_page = (uint64_t)adr >> 12;
1555 long offset = adr_page - pc_page;
1556 int offset_lo = offset & 3;
1557 offset >>= 2;
1558 starti;
1559 f(1, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
1560 rf(Rd, 0);
1561 }
1562
1563 #undef starti
1564
1565 Address::Address(address target, relocInfo::relocType rtype) : _mode(literal){
1566 _is_lval = false;
1567 _target = target;
1568 switch (rtype) {
1569 case relocInfo::oop_type:
1570 case relocInfo::metadata_type:
1571 // Oops are a special case. Normally they would be their own section
1572 // but in cases like icBuffer they are literals in the code stream that
1573 // we don't have a section for. We use none so that we get a literal address
1574 // which is always patchable.
1575 break;
1684 op = negated_op;
1685 }
1686 assert(Rd != sp || imm % 16 == 0, "misaligned stack");
1687 if (imm >= (1 << 11)
1688 && ((imm >> 12) << 12 == imm)) {
1689 imm >>= 12;
1690 shift = true;
1691 }
1692 f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10);
1693
1694 // add/subtract immediate ops with the S bit set treat r31 as zr;
1695 // with S unset they use sp.
1696 if (sets_flags)
1697 zrf(Rd, 0);
1698 else
1699 srf(Rd, 0);
1700
1701 srf(Rn, 5);
1702 }
1703
1704 bool Assembler::operand_valid_for_add_sub_immediate(long imm) {
1705 bool shift = false;
1706 unsigned long uimm = uabs(imm);
1707 if (uimm < (1 << 12))
1708 return true;
1709 if (uimm < (1 << 24)
1710 && ((uimm >> 12) << 12 == uimm)) {
1711 return true;
1712 }
1713 return false;
1714 }
1715
1716 bool Assembler::operand_valid_for_logical_immediate(bool is32, uint64_t imm) {
1717 return encode_logical_immediate(is32, imm) != 0xffffffff;
1718 }
1719
1720 static uint64_t doubleTo64Bits(jdouble d) {
1721 union {
1722 jdouble double_value;
1723 uint64_t double_bits;
1724 };
1725
1726 double_value = d;
|
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 #include <stdio.h>
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "asm/assembler.hpp"
30 #include "asm/assembler.inline.hpp"
31 #include "interpreter/interpreter.hpp"
32
33 #ifndef PRODUCT
34 const uint64_t Assembler::asm_bp = 0x00007fffee09ac88;
35 #endif
36
37 #include "compiler/disassembler.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "runtime/interfaceSupport.inline.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #include "immediate_aarch64.hpp"
42
43 extern "C" void entry(CodeBuffer *cb);
44
45 #define __ _masm.
46 #ifdef PRODUCT
47 #define BLOCK_COMMENT(str) /* nothing */
48 #else
49 #define BLOCK_COMMENT(str) block_comment(str)
50 #endif
51
52 #define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":")
53
54 static float unpack(unsigned value);
1476 RelocationHolder const& rspec,
1477 int format) {
1478
1479 assert(inst_mark() != NULL, "must be inside InstructionMark");
1480 // Do not use AbstractAssembler::relocate, which is not intended for
1481 // embedded words. Instead, relocate to the enclosing instruction.
1482 code_section()->relocate(inst_mark(), rspec, format);
1483 emit_int64(data);
1484 }
1485
1486 extern "C" {
1487 void das(uint64_t start, int len) {
1488 ResourceMark rm;
1489 len <<= 2;
1490 if (len < 0)
1491 Disassembler::decode((address)start + len, (address)start);
1492 else
1493 Disassembler::decode((address)start, (address)start + len);
1494 }
1495
1496 JNIEXPORT void das1(uint64_t insn) {
1497 das(insn, 1);
1498 }
1499 }
1500
1501 #define gas_assert(ARG1) assert(ARG1, #ARG1)
1502
1503 #define __ as->
1504
1505 void Address::lea(MacroAssembler *as, Register r) const {
1506 Relocation* reloc = _rspec.reloc();
1507 relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
1508
1509 switch(_mode) {
1510 case base_plus_offset: {
1511 if (_offset == 0 && _base == r) // it's a nop
1512 break;
1513 if (_offset > 0)
1514 __ add(r, _base, _offset);
1515 else
1516 __ sub(r, _base, -_offset);
1517 break;
1518 }
1519 case base_plus_offset_reg: {
1520 __ add(r, _base, _index, _ext.op(), MAX(_ext.shift(), 0));
1521 break;
1522 }
1523 case literal: {
1524 if (rtype == relocInfo::none)
1525 __ mov(r, target());
1526 else
1527 __ movptr(r, (uint64_t)target());
1528 break;
1529 }
1530 default:
1531 ShouldNotReachHere();
1532 }
1533 }
1534
1535 void Assembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) {
1536 ShouldNotReachHere();
1537 }
1538
1539 #undef __
1540
1541 #define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use)
1542
1543 void Assembler::adr(Register Rd, address adr) {
1544 int64_t offset = adr - pc();
1545 int offset_lo = offset & 3;
1546 offset >>= 2;
1547 starti;
1548 f(0, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
1549 rf(Rd, 0);
1550 }
1551
1552 void Assembler::_adrp(Register Rd, address adr) {
1553 uint64_t pc_page = (uint64_t)pc() >> 12;
1554 uint64_t adr_page = (uint64_t)adr >> 12;
1555 int64_t offset = adr_page - pc_page;
1556 int offset_lo = offset & 3;
1557 offset >>= 2;
1558 starti;
1559 f(1, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
1560 rf(Rd, 0);
1561 }
1562
1563 #undef starti
1564
1565 Address::Address(address target, relocInfo::relocType rtype) : _mode(literal){
1566 _is_lval = false;
1567 _target = target;
1568 switch (rtype) {
1569 case relocInfo::oop_type:
1570 case relocInfo::metadata_type:
1571 // Oops are a special case. Normally they would be their own section
1572 // but in cases like icBuffer they are literals in the code stream that
1573 // we don't have a section for. We use none so that we get a literal address
1574 // which is always patchable.
1575 break;
1684 op = negated_op;
1685 }
1686 assert(Rd != sp || imm % 16 == 0, "misaligned stack");
1687 if (imm >= (1 << 11)
1688 && ((imm >> 12) << 12 == imm)) {
1689 imm >>= 12;
1690 shift = true;
1691 }
1692 f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10);
1693
1694 // add/subtract immediate ops with the S bit set treat r31 as zr;
1695 // with S unset they use sp.
1696 if (sets_flags)
1697 zrf(Rd, 0);
1698 else
1699 srf(Rd, 0);
1700
1701 srf(Rn, 5);
1702 }
1703
1704 bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) {
1705 bool shift = false;
1706 uint64_t uimm = uabs(imm);
1707 if (uimm < (1 << 12))
1708 return true;
1709 if (uimm < (1 << 24)
1710 && ((uimm >> 12) << 12 == uimm)) {
1711 return true;
1712 }
1713 return false;
1714 }
1715
1716 bool Assembler::operand_valid_for_logical_immediate(bool is32, uint64_t imm) {
1717 return encode_logical_immediate(is32, imm) != 0xffffffff;
1718 }
1719
1720 static uint64_t doubleTo64Bits(jdouble d) {
1721 union {
1722 jdouble double_value;
1723 uint64_t double_bits;
1724 };
1725
1726 double_value = d;
|