< prev index next >

src/hotspot/cpu/aarch64/assembler_aarch64.cpp

Print this page
8248238: Adding Windows support to OpenJDK on AArch64

Summary: LP64 vs LLP64 changes to add Windows support

Contributed-by: Monica Beckwith <monica.beckwith@microsoft.com>, Ludovic Henry <luhenry@microsoft.com>
Reviewed-by:


  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;


< prev index next >