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() {
3463 uint64_t con = (uint64_t)$src$$constant;
3464 if (con == 0) {
3465 __ mov(dst_reg, zr);
3466 } else {
3467 __ mov(dst_reg, con);
3468 }
3469 %}
3470
3471 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3472 Register dst_reg = as_Register($dst$$reg);
3473 address con = (address)$src$$constant;
3474 if (con == nullptr || con == (address)1) {
3475 ShouldNotReachHere();
3476 } else {
3477 relocInfo::relocType rtype = $src->constant_reloc();
3478 if (rtype == relocInfo::oop_type) {
3479 __ movoop(dst_reg, (jobject)con);
3480 } else if (rtype == relocInfo::metadata_type) {
3481 __ mov_metadata(dst_reg, (Metadata*)con);
3482 } else {
3483 assert(rtype == relocInfo::none, "unexpected reloc type");
3484 if (! __ is_valid_AArch64_address(con) ||
3485 con < (address)(uintptr_t)os::vm_page_size()) {
3486 __ mov(dst_reg, con);
3487 } else {
3488 uint64_t offset;
3489 __ adrp(dst_reg, con, offset);
3490 __ add(dst_reg, dst_reg, offset);
3491 }
3492 }
3493 }
3494 %}
3495
3496 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3497 Register dst_reg = as_Register($dst$$reg);
3498 __ mov(dst_reg, zr);
3499 %}
3500
3501 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3502 Register dst_reg = as_Register($dst$$reg);
3503 __ mov(dst_reg, (uint64_t)1);
4595 predicate(n->get_ptr() == 0);
4596 match(ConP);
4597
4598 op_cost(0);
4599 format %{ %}
4600 interface(CONST_INTER);
4601 %}
4602
4603 // Pointer Immediate One
4604 // this is used in object initialization (initial object header)
4605 operand immP_1()
4606 %{
4607 predicate(n->get_ptr() == 1);
4608 match(ConP);
4609
4610 op_cost(0);
4611 format %{ %}
4612 interface(CONST_INTER);
4613 %}
4614
4615 // Float and Double operands
4616 // Double Immediate
4617 operand immD()
4618 %{
4619 match(ConD);
4620 op_cost(0);
4621 format %{ %}
4622 interface(CONST_INTER);
4623 %}
4624
4625 // Double Immediate: +0.0d
4626 operand immD0()
4627 %{
4628 predicate(jlong_cast(n->getd()) == 0);
4629 match(ConD);
4630
4631 op_cost(0);
4632 format %{ %}
4633 interface(CONST_INTER);
4634 %}
6958
6959 ins_encode(aarch64_enc_mov_p0(dst, con));
6960
6961 ins_pipe(ialu_imm);
6962 %}
6963
6964 // Load Pointer Constant One
6965
6966 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6967 %{
6968 match(Set dst con);
6969
6970 ins_cost(INSN_COST);
6971 format %{ "mov $dst, $con\t# nullptr ptr" %}
6972
6973 ins_encode(aarch64_enc_mov_p1(dst, con));
6974
6975 ins_pipe(ialu_imm);
6976 %}
6977
6978 // Load Narrow Pointer Constant
6979
6980 instruct loadConN(iRegNNoSp dst, immN con)
6981 %{
6982 match(Set dst con);
6983
6984 ins_cost(INSN_COST * 4);
6985 format %{ "mov $dst, $con\t# compressed ptr" %}
6986
6987 ins_encode(aarch64_enc_mov_n(dst, con));
6988
6989 ins_pipe(ialu_imm);
6990 %}
6991
6992 // Load Narrow Null Pointer Constant
6993
6994 instruct loadConN0(iRegNNoSp dst, immN0 con)
6995 %{
6996 match(Set dst con);
6997
|
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() {
3463 uint64_t con = (uint64_t)$src$$constant;
3464 if (con == 0) {
3465 __ mov(dst_reg, zr);
3466 } else {
3467 __ mov(dst_reg, con);
3468 }
3469 %}
3470
3471 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{
3472 Register dst_reg = as_Register($dst$$reg);
3473 address con = (address)$src$$constant;
3474 if (con == nullptr || con == (address)1) {
3475 ShouldNotReachHere();
3476 } else {
3477 relocInfo::relocType rtype = $src->constant_reloc();
3478 if (rtype == relocInfo::oop_type) {
3479 __ movoop(dst_reg, (jobject)con);
3480 } else if (rtype == relocInfo::metadata_type) {
3481 __ mov_metadata(dst_reg, (Metadata*)con);
3482 } else {
3483 assert(rtype == relocInfo::none || rtype == relocInfo::external_word_type, "unexpected reloc type");
3484 if (! __ is_valid_AArch64_address(con) ||
3485 con < (address)(uintptr_t)os::vm_page_size()) {
3486 __ mov(dst_reg, con);
3487 } else {
3488 uint64_t offset;
3489 __ adrp(dst_reg, con, offset);
3490 __ add(dst_reg, dst_reg, offset);
3491 }
3492 }
3493 }
3494 %}
3495
3496 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{
3497 Register dst_reg = as_Register($dst$$reg);
3498 __ mov(dst_reg, zr);
3499 %}
3500
3501 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{
3502 Register dst_reg = as_Register($dst$$reg);
3503 __ mov(dst_reg, (uint64_t)1);
4595 predicate(n->get_ptr() == 0);
4596 match(ConP);
4597
4598 op_cost(0);
4599 format %{ %}
4600 interface(CONST_INTER);
4601 %}
4602
4603 // Pointer Immediate One
4604 // this is used in object initialization (initial object header)
4605 operand immP_1()
4606 %{
4607 predicate(n->get_ptr() == 1);
4608 match(ConP);
4609
4610 op_cost(0);
4611 format %{ %}
4612 interface(CONST_INTER);
4613 %}
4614
4615 // AOT Runtime Constants Address
4616 operand immAOTRuntimeConstantsAddress()
4617 %{
4618 // Check if the address is in the range of AOT Runtime Constants
4619 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr())));
4620 match(ConP);
4621
4622 op_cost(0);
4623 format %{ %}
4624 interface(CONST_INTER);
4625 %}
4626
4627 // Float and Double operands
4628 // Double Immediate
4629 operand immD()
4630 %{
4631 match(ConD);
4632 op_cost(0);
4633 format %{ %}
4634 interface(CONST_INTER);
4635 %}
4636
4637 // Double Immediate: +0.0d
4638 operand immD0()
4639 %{
4640 predicate(jlong_cast(n->getd()) == 0);
4641 match(ConD);
4642
4643 op_cost(0);
4644 format %{ %}
4645 interface(CONST_INTER);
4646 %}
6970
6971 ins_encode(aarch64_enc_mov_p0(dst, con));
6972
6973 ins_pipe(ialu_imm);
6974 %}
6975
6976 // Load Pointer Constant One
6977
6978 instruct loadConP1(iRegPNoSp dst, immP_1 con)
6979 %{
6980 match(Set dst con);
6981
6982 ins_cost(INSN_COST);
6983 format %{ "mov $dst, $con\t# nullptr ptr" %}
6984
6985 ins_encode(aarch64_enc_mov_p1(dst, con));
6986
6987 ins_pipe(ialu_imm);
6988 %}
6989
6990 instruct loadAOTRCAddress(iRegPNoSp dst, immAOTRuntimeConstantsAddress con)
6991 %{
6992 match(Set dst con);
6993
6994 ins_cost(INSN_COST);
6995 format %{ "adr $dst, $con\t# AOT Runtime Constants Address" %}
6996
6997 ins_encode %{
6998 __ load_aotrc_address($dst$$Register, (address)$con$$constant);
6999 %}
7000
7001 ins_pipe(ialu_imm);
7002 %}
7003
7004 // Load Narrow Pointer Constant
7005
7006 instruct loadConN(iRegNNoSp dst, immN con)
7007 %{
7008 match(Set dst con);
7009
7010 ins_cost(INSN_COST * 4);
7011 format %{ "mov $dst, $con\t# compressed ptr" %}
7012
7013 ins_encode(aarch64_enc_mov_n(dst, con));
7014
7015 ins_pipe(ialu_imm);
7016 %}
7017
7018 // Load Narrow Null Pointer Constant
7019
7020 instruct loadConN0(iRegNNoSp dst, immN0 con)
7021 %{
7022 match(Set dst con);
7023
|