1164 #include "opto/convertnode.hpp"
1165 #include "runtime/objectMonitor.hpp"
1166
1167 extern RegMask _ANY_REG32_mask;
1168 extern RegMask _ANY_REG_mask;
1169 extern RegMask _PTR_REG_mask;
1170 extern RegMask _NO_SPECIAL_REG32_mask;
1171 extern RegMask _NO_SPECIAL_REG_mask;
1172 extern RegMask _NO_SPECIAL_PTR_REG_mask;
1173 extern RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask;
1174
1175 class CallStubImpl {
1176
1177 //--------------------------------------------------------------
1178 //---< Used for optimization in Compile::shorten_branches >---
1179 //--------------------------------------------------------------
1180
1181 public:
1182 // Size of call trampoline stub.
1183 static uint size_call_trampoline() {
1184 return 0; // no call trampolines on this platform
1185 }
1186
1187 // number of relocations needed by a call trampoline stub
1188 static uint reloc_call_trampoline() {
1189 return 0; // no call trampolines on this platform
1190 }
1191 };
1192
1193 class HandlerImpl {
1194
1195 public:
1196
1197 static int emit_exception_handler(C2_MacroAssembler *masm);
1198 static int emit_deopt_handler(C2_MacroAssembler* masm);
1199
1200 static uint size_exception_handler() {
1201 return MacroAssembler::far_codestub_branch_size();
1202 }
1203
1204 static uint size_deopt_handler() {
3467 uint64_t con = (uint64_t)$src$$constant;
3468 if (con == 0) {
3469 __ mov(dst_reg, zr);
3470 } else {
3471 __ mov(dst_reg, con);
3472 }
3473 %}
3474
3475 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3476 Register dst_reg = as_Register($dst$$reg);
3477 address con = (address)$src$$constant;
3478 if (con == nullptr || con == (address)1) {
3479 ShouldNotReachHere();
3480 } else {
3481 relocInfo::relocType rtype = $src->constant_reloc();
3482 if (rtype == relocInfo::oop_type) {
3483 __ movoop(dst_reg, (jobject)con);
3484 } else if (rtype == relocInfo::metadata_type) {
3485 __ mov_metadata(dst_reg, (Metadata*)con);
3486 } else {
3487 assert(rtype == relocInfo::none, "unexpected reloc type");
3488 if (! __ is_valid_AArch64_address(con) ||
3489 con < (address)(uintptr_t)os::vm_page_size()) {
3490 __ mov(dst_reg, con);
3491 } else {
3492 uint64_t offset;
3493 __ adrp(dst_reg, con, offset);
3494 __ add(dst_reg, dst_reg, offset);
3495 }
3496 }
3497 }
3498 %}
3499
3500 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3501 Register dst_reg = as_Register($dst$$reg);
3502 __ mov(dst_reg, zr);
3503 %}
3504
3505 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3506 Register dst_reg = as_Register($dst$$reg);
3507 __ mov(dst_reg, (uint64_t)1);
4599 predicate(n->get_ptr() == 0);
4600 match(ConP);
4601
4602 op_cost(0);
4603 format %{ %}
4604 interface(CONST_INTER);
4605 %}
4606
4607 // Pointer Immediate One
4608 // this is used in object initialization (initial object header)
4609 operand immP_1()
4610 %{
4611 predicate(n->get_ptr() == 1);
4612 match(ConP);
4613
4614 op_cost(0);
4615 format %{ %}
4616 interface(CONST_INTER);
4617 %}
4618
4619 // Float and Double operands
4620 // Double Immediate
4621 operand immD()
4622 %{
4623 match(ConD);
4624 op_cost(0);
4625 format %{ %}
4626 interface(CONST_INTER);
4627 %}
4628
4629 // Double Immediate: +0.0d
4630 operand immD0()
4631 %{
4632 predicate(jlong_cast(n->getd()) == 0);
4633 match(ConD);
4634
4635 op_cost(0);
4636 format %{ %}
4637 interface(CONST_INTER);
4638 %}
6965
6966 ins_encode(aarch64_enc_mov_p0(dst, con));
6967
6968 ins_pipe(ialu_imm);
6969 %}
6970
6971 // Load Pointer Constant One
6972
6973 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6974 %{
6975 match(Set dst con);
6976
6977 ins_cost(INSN_COST);
6978 format %{ "mov $dst, $con\t# nullptr ptr" %}
6979
6980 ins_encode(aarch64_enc_mov_p1(dst, con));
6981
6982 ins_pipe(ialu_imm);
6983 %}
6984
6985 // Load Narrow Pointer Constant
6986
6987 instruct loadConN(iRegNNoSp dst, immN con)
6988 %{
6989 match(Set dst con);
6990
6991 ins_cost(INSN_COST * 4);
6992 format %{ "mov $dst, $con\t# compressed ptr" %}
6993
6994 ins_encode(aarch64_enc_mov_n(dst, con));
6995
6996 ins_pipe(ialu_imm);
6997 %}
6998
6999 // Load Narrow Null Pointer Constant
7000
7001 instruct loadConN0(iRegNNoSp dst, immN0 con)
7002 %{
7003 match(Set dst con);
7004
|
1164 #include "opto/convertnode.hpp"
1165 #include "runtime/objectMonitor.hpp"
1166
1167 extern RegMask _ANY_REG32_mask;
1168 extern RegMask _ANY_REG_mask;
1169 extern RegMask _PTR_REG_mask;
1170 extern RegMask _NO_SPECIAL_REG32_mask;
1171 extern RegMask _NO_SPECIAL_REG_mask;
1172 extern RegMask _NO_SPECIAL_PTR_REG_mask;
1173 extern RegMask _NO_SPECIAL_NO_RFP_PTR_REG_mask;
1174
1175 class CallStubImpl {
1176
1177 //--------------------------------------------------------------
1178 //---< Used for optimization in Compile::shorten_branches >---
1179 //--------------------------------------------------------------
1180
1181 public:
1182 // Size of call trampoline stub.
1183 static uint size_call_trampoline() {
1184 return MacroAssembler::max_trampoline_stub_size(); // no call trampolines on this platform
1185 }
1186
1187 // number of relocations needed by a call trampoline stub
1188 static uint reloc_call_trampoline() {
1189 return 0; // no call trampolines on this platform
1190 }
1191 };
1192
1193 class HandlerImpl {
1194
1195 public:
1196
1197 static int emit_exception_handler(C2_MacroAssembler *masm);
1198 static int emit_deopt_handler(C2_MacroAssembler* masm);
1199
1200 static uint size_exception_handler() {
1201 return MacroAssembler::far_codestub_branch_size();
1202 }
1203
1204 static uint size_deopt_handler() {
3467 uint64_t con = (uint64_t)$src$$constant;
3468 if (con == 0) {
3469 __ mov(dst_reg, zr);
3470 } else {
3471 __ mov(dst_reg, con);
3472 }
3473 %}
3474
3475 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3476 Register dst_reg = as_Register($dst$$reg);
3477 address con = (address)$src$$constant;
3478 if (con == nullptr || con == (address)1) {
3479 ShouldNotReachHere();
3480 } else {
3481 relocInfo::relocType rtype = $src->constant_reloc();
3482 if (rtype == relocInfo::oop_type) {
3483 __ movoop(dst_reg, (jobject)con);
3484 } else if (rtype == relocInfo::metadata_type) {
3485 __ mov_metadata(dst_reg, (Metadata*)con);
3486 } else {
3487 assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type");
3488 if (! __ is_valid_AArch64_address(con) ||
3489 con < (address)(uintptr_t)os::vm_page_size()) {
3490 __ mov(dst_reg, con);
3491 } else {
3492 uint64_t offset;
3493 __ adrp(dst_reg, con, offset);
3494 __ add(dst_reg, dst_reg, offset);
3495 }
3496 }
3497 }
3498 %}
3499
3500 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3501 Register dst_reg = as_Register($dst$$reg);
3502 __ mov(dst_reg, zr);
3503 %}
3504
3505 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3506 Register dst_reg = as_Register($dst$$reg);
3507 __ mov(dst_reg, (uint64_t)1);
4599 predicate(n->get_ptr() == 0);
4600 match(ConP);
4601
4602 op_cost(0);
4603 format %{ %}
4604 interface(CONST_INTER);
4605 %}
4606
4607 // Pointer Immediate One
4608 // this is used in object initialization (initial object header)
4609 operand immP_1()
4610 %{
4611 predicate(n->get_ptr() == 1);
4612 match(ConP);
4613
4614 op_cost(0);
4615 format %{ %}
4616 interface(CONST_INTER);
4617 %}
4618
4619 // Card Table Byte Map Base
4620 operand immByteMapBase()
4621 %{
4622 // Get base of card map
4623 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
4624 is_card_table_address((address)(n->get_ptr())));
4625 match(ConP);
4626
4627 op_cost(0);
4628 format %{ %}
4629 interface(CONST_INTER);
4630 %}
4631
4632 // AOT Runtime Constants Address
4633 operand immAOTRuntimeConstantsAddress()
4634 %{
4635 // Check if the address is in the range of AOT Runtime Constants
4636 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
4637 match(ConP);
4638
4639 op_cost(0);
4640 format %{ %}
4641 interface(CONST_INTER);
4642 %}
4643
4644 // Float and Double operands
4645 // Double Immediate
4646 operand immD()
4647 %{
4648 match(ConD);
4649 op_cost(0);
4650 format %{ %}
4651 interface(CONST_INTER);
4652 %}
4653
4654 // Double Immediate: +0.0d
4655 operand immD0()
4656 %{
4657 predicate(jlong_cast(n->getd()) == 0);
4658 match(ConD);
4659
4660 op_cost(0);
4661 format %{ %}
4662 interface(CONST_INTER);
4663 %}
6990
6991 ins_encode(aarch64_enc_mov_p0(dst, con));
6992
6993 ins_pipe(ialu_imm);
6994 %}
6995
6996 // Load Pointer Constant One
6997
6998 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6999 %{
7000 match(Set dst con);
7001
7002 ins_cost(INSN_COST);
7003 format %{ "mov $dst, $con\t# nullptr ptr" %}
7004
7005 ins_encode(aarch64_enc_mov_p1(dst, con));
7006
7007 ins_pipe(ialu_imm);
7008 %}
7009
7010 // Load Byte Map Base Constant
7011
7012 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
7013 %{
7014 match(Set dst con);
7015
7016 ins_cost(INSN_COST);
7017 format %{ "adr $dst, $con\t# Byte Map Base" %}
7018
7019 ins_encode %{
7020 __ load_byte_map_base($dst$$Register);
7021 %}
7022
7023 ins_pipe(ialu_imm);
7024 %}
7025
7026 instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con)
7027 %{
7028 match(Set dst con);
7029
7030 ins_cost(INSN_COST);
7031 format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %}
7032
7033 ins_encode %{
7034 __ load_aotrc_address($dst$$Register, (address)$con$$constant);
7035 %}
7036
7037 ins_pipe(ialu_imm);
7038 %}
7039
7040 // Load Narrow Pointer Constant
7041
7042 instruct loadConN(iRegNNoSp dst, immN con)
7043 %{
7044 match(Set dst con);
7045
7046 ins_cost(INSN_COST * 4);
7047 format %{ "mov $dst, $con\t# compressed ptr" %}
7048
7049 ins_encode(aarch64_enc_mov_n(dst, con));
7050
7051 ins_pipe(ialu_imm);
7052 %}
7053
7054 // Load Narrow Null Pointer Constant
7055
7056 instruct loadConN0(iRegNNoSp dst, immN0 con)
7057 %{
7058 match(Set dst con);
7059
|