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 %}
6962
6963 ins_encode(aarch64_enc_mov_p0(dst, con));
6964
6965 ins_pipe(ialu_imm);
6966 %}
6967
6968 // Load Pointer Constant One
6969
6970 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6971 %{
6972 match(Set dst con);
6973
6974 ins_cost(INSN_COST);
6975 format %{ "mov $dst, $con\t# nullptr ptr" %}
6976
6977 ins_encode(aarch64_enc_mov_p1(dst, con));
6978
6979 ins_pipe(ialu_imm);
6980 %}
6981
6982 // Load Narrow Pointer Constant
6983
6984 instruct loadConN(iRegNNoSp dst, immN con)
6985 %{
6986 match(Set dst con);
6987
6988 ins_cost(INSN_COST * 4);
6989 format %{ "mov $dst, $con\t# compressed ptr" %}
6990
6991 ins_encode(aarch64_enc_mov_n(dst, con));
6992
6993 ins_pipe(ialu_imm);
6994 %}
6995
6996 // Load Narrow Null Pointer Constant
6997
6998 instruct loadConN0(iRegNNoSp dst, immN0 con)
6999 %{
7000 match(Set dst con);
7001
|
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 // AOT Runtime Constants Address
4620 operand immAOTRuntimeConstantsAddress()
4621 %{
4622 // Check if the address is in the range of AOT Runtime Constants
4623 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
4624 match(ConP);
4625
4626 op_cost(0);
4627 format %{ %}
4628 interface(CONST_INTER);
4629 %}
4630
4631 // Float and Double operands
4632 // Double Immediate
4633 operand immD()
4634 %{
4635 match(ConD);
4636 op_cost(0);
4637 format %{ %}
4638 interface(CONST_INTER);
4639 %}
4640
4641 // Double Immediate: +0.0d
4642 operand immD0()
4643 %{
4644 predicate(jlong_cast(n->getd()) == 0);
4645 match(ConD);
4646
4647 op_cost(0);
4648 format %{ %}
4649 interface(CONST_INTER);
4650 %}
6974
6975 ins_encode(aarch64_enc_mov_p0(dst, con));
6976
6977 ins_pipe(ialu_imm);
6978 %}
6979
6980 // Load Pointer Constant One
6981
6982 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6983 %{
6984 match(Set dst con);
6985
6986 ins_cost(INSN_COST);
6987 format %{ "mov $dst, $con\t# nullptr ptr" %}
6988
6989 ins_encode(aarch64_enc_mov_p1(dst, con));
6990
6991 ins_pipe(ialu_imm);
6992 %}
6993
6994 instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con)
6995 %{
6996 match(Set dst con);
6997
6998 ins_cost(INSN_COST);
6999 format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %}
7000
7001 ins_encode %{
7002 __ load_aotrc_address($dst$$Register, (address)$con$$constant);
7003 %}
7004
7005 ins_pipe(ialu_imm);
7006 %}
7007
7008 // Load Narrow Pointer Constant
7009
7010 instruct loadConN(iRegNNoSp dst, immN con)
7011 %{
7012 match(Set dst con);
7013
7014 ins_cost(INSN_COST * 4);
7015 format %{ "mov $dst, $con\t# compressed ptr" %}
7016
7017 ins_encode(aarch64_enc_mov_n(dst, con));
7018
7019 ins_pipe(ialu_imm);
7020 %}
7021
7022 // Load Narrow Null Pointer Constant
7023
7024 instruct loadConN0(iRegNNoSp dst, immN0 con)
7025 %{
7026 match(Set dst con);
7027
|