--- /dev/null 2016-08-24 15:41:39.598575000 -0400 +++ new/src/cpu/arm/vm/nativeInst_arm_64.hpp 2016-12-13 12:53:02.424854158 -0500 @@ -0,0 +1,772 @@ +/* + * 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 "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,