/* * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef CPU_ARM_VM_NATIVEINST_ARM_64_HPP #define CPU_ARM_VM_NATIVEINST_ARM_64_HPP #include "asm/macroAssembler.hpp" #include "code/codeCache.hpp" #include "code/codeCacheExtensions.hpp" #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" // ------------------------------------------------------------------- // Some experimental projects extend the ARM back-end by implementing // what the front-end usually assumes is a single native instruction // with a sequence of instructions. // // The 'Raw' variants are the low level initial code (usually one // instruction wide but some of them were already composed // instructions). They should be used only by the back-end. // // The non-raw classes are the front-end entry point, hiding potential // back-end extensions or the actual instructions size. class NativeInstruction; class RawNativeInstruction VALUE_OBJ_CLASS_SPEC { public: enum ARM_specific { instruction_size = Assembler::InstructionSize, instruction_size_in_bits = instruction_size * BitsPerByte, }; // illegal instruction used by NativeJump::patch_verified_entry static const int zombie_illegal_instruction = 0xd4000542; // hvc #42 address addr_at(int offset) const { return (address)this + offset; } address instruction_address() const { return addr_at(0); } address next_raw_instruction_address() const { return addr_at(instruction_size); } static RawNativeInstruction* at(address address) { return (RawNativeInstruction*)address; } RawNativeInstruction* next_raw() const { return at(next_raw_instruction_address()); } int encoding() const { return *(int*)this; } void set_encoding(int value) { int old = encoding(); if (old != value) { *(int*)this = value; ICache::invalidate_word((address)this); } } bool is_nop() const { return encoding() == (int)0xd503201f; } bool is_b() const { return (encoding() & 0xfc000000) == 0x14000000; } // unconditional branch bool is_b_cond() const { return (encoding() & 0xff000010) == 0x54000000; } // conditional branch bool is_bl() const { return (encoding() & 0xfc000000) == 0x94000000; } bool is_br() const { return (encoding() & 0xfffffc1f) == 0xd61f0000; } bool is_blr() const { return (encoding() & 0xfffffc1f) == 0xd63f0000; } bool is_ldr_literal() const { return (encoding() & 0xff000000) == 0x58000000; } bool is_adr_aligned() const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn,