--- /dev/null 2016-08-24 15:41:39.598575000 -0400 +++ new/hotspot/src/cpu/arm/vm/register_arm.hpp 2016-12-02 11:22:59.993513823 -0500 @@ -0,0 +1,570 @@ +/* + * Copyright (c) 2008, 2015, 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_REGISTER_ARM_HPP +#define CPU_ARM_VM_REGISTER_ARM_HPP + +#include "asm/register.hpp" +#include "vm_version_arm.hpp" + +class VMRegImpl; +typedef VMRegImpl* VMReg; + +// These are declared ucontext.h +#undef R0 +#undef R1 +#undef R2 +#undef R3 +#undef R4 +#undef R5 +#undef R6 +#undef R7 +#undef R8 +#undef R9 +#undef R10 +#undef R11 +#undef R12 +#undef R13 +#undef R14 +#undef R15 + +#define R(r) ((Register)(r)) + +///////////////////////////////// +// Support for different ARM ABIs +// Note: default ABI is for linux + + +// R9_IS_SCRATCHED +// +// The ARM ABI does not guarantee that R9 is callee saved. +// Set R9_IS_SCRATCHED to 1 to ensure it is properly saved/restored by +// the caller. +#ifndef R9_IS_SCRATCHED +// Default: R9 is callee saved +#define R9_IS_SCRATCHED 0 +#endif + +#ifndef AARCH64 +// FP_REG_NUM +// +// The ARM ABI does not state which register is used for the frame pointer. +// Note: for the ABIs we are currently aware of, FP is currently +// either R7 or R11. Code may have to be extended if a third register +// register must be supported (see altFP_7_11). +#ifndef FP_REG_NUM +// Default: FP is R11 +#define FP_REG_NUM 11 +#endif +#endif // AARCH64 + +// ALIGN_WIDE_ARGUMENTS +// +// The ARM ABI requires 64-bits arguments to be aligned on 4 words +// or on even registers. Set ALIGN_WIDE_ARGUMENTS to 1 for that behavior. +// +// Unfortunately, some platforms do not endorse that part of the ABI. +// +// We are aware of one which expects 64-bit arguments to only be 4 +// bytes aligned and can for instance use R3 + a stack slot for such +// an argument. +// +// This is the behavor implemented if (ALIGN_WIDE_ARGUMENTS == 0) +#ifndef ALIGN_WIDE_ARGUMENTS +// Default: align on 8 bytes and avoid using +#define ALIGN_WIDE_ARGUMENTS 1 +#endif + +#define R0 ((Register)0) +#define R1 ((Register)1) +#define R2 ((Register)2) +#define R3 ((Register)3) +#define R4 ((Register)4) +#define R5 ((Register)5) +#define R6 ((Register)6) +#define R7 ((Register)7) +#define R8 ((Register)8) +#define R9 ((Register)9) +#define R10 ((Register)10) +#define R11 ((Register)11) +#define R12 ((Register)12) +#define R13 ((Register)13) +#define R14 ((Register)14) +#define R15 ((Register)15) + +#ifdef AARCH64 + +#define R16 ((Register)16) +#define R17 ((Register)17) +#define R18 ((Register)18) +#define R19 ((Register)19) +#define R20 ((Register)20) +#define R21 ((Register)21) +#define R22 ((Register)22) +#define R23 ((Register)23) +#define R24 ((Register)24) +#define R25 ((Register)25) +#define R26 ((Register)26) +#define R27 ((Register)27) +#define R28 ((Register)28) +#define R29 ((Register)29) +#define R30 ((Register)30) +#define ZR ((Register)31) +#define SP ((Register)32) + +#define FP R29 +#define LR R30 + +#define altFP_7_11 R7 + +#else // !AARCH64 + +#define FP ((Register)FP_REG_NUM) + +// Safe use of registers which may be FP on some platforms. +// +// altFP_7_11: R7 if not equal to FP, else R11 (the default FP) +// +// Note: add additional altFP_#_11 for each register potentially used +// as FP on supported ABIs (and replace R# by altFP_#_11). altFP_#_11 +// must be #define to R11 if and only if # is FP_REG_NUM. +#if (FP_REG_NUM == 7) +#define altFP_7_11 ((Register)11) +#else +#define altFP_7_11 ((Register)7) +#endif +#define SP R13 +#define LR R14 +#define PC R15 + +#endif // !AARCH64 + + +class RegisterImpl; +typedef RegisterImpl* Register; + +inline Register as_Register(int encoding) { + return (Register)(intptr_t)encoding; +} + +class RegisterImpl : public AbstractRegisterImpl { + public: + enum { +#ifdef AARCH64 + number_of_gprs = 31, + zr_sp_encoding = 31, +#endif + number_of_registers = AARCH64_ONLY(number_of_gprs + 2) NOT_AARCH64(16) + }; + + Register successor() const { return as_Register(encoding() + 1); } + + inline friend Register as_Register(int encoding); + + VMReg as_VMReg(); + + // accessors + int encoding() const { assert(is_valid(), "invalid register"); return value(); } + const char* name() const; + +#ifdef AARCH64 + int encoding_with_zr() const { assert (is_valid_gpr_or_zr(), "invalid register"); return (this == ZR) ? zr_sp_encoding : value(); } + int encoding_with_sp() const { assert (is_valid_gpr_or_sp(), "invalid register"); return (this == SP) ? zr_sp_encoding : value(); } +#endif + + // testers + bool is_valid() const { return 0 <= value() && value() < number_of_registers; } + +#ifdef AARCH64 + bool is_valid_gpr() const { return (0 <= value() && value() < number_of_gprs); } + bool is_valid_gpr_or_zr() const { return is_valid_gpr() || (this == ZR); } + bool is_valid_gpr_or_sp() const { return is_valid_gpr() || (this == SP); } +#endif +}; + +CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); + + +// Use FloatRegister as shortcut +class FloatRegisterImpl; +typedef FloatRegisterImpl* FloatRegister; + +inline FloatRegister as_FloatRegister(int encoding) { + return (FloatRegister)(intptr_t)encoding; +} + +class FloatRegisterImpl : public AbstractRegisterImpl { + public: + enum { +#ifdef AARCH64 + number_of_registers = 32 +#else + number_of_registers = NOT_COMPILER2(32) COMPILER2_PRESENT(64) +#endif + }; + + inline friend FloatRegister as_FloatRegister(int encoding); + + VMReg as_VMReg(); + + int encoding() const { assert(is_valid(), "invalid register"); return value(); } + bool is_valid() const { return 0 <= (intx)this && (intx)this < number_of_registers; } + FloatRegister successor() const { return as_FloatRegister(encoding() + 1); } + + const char* name() const; + +#ifndef AARCH64 + int hi_bits() const { + return (encoding() >> 1) & 0xf; + } + + int lo_bit() const { + return encoding() & 1; + } + + int hi_bit() const { + return encoding() >> 5; + } +#endif // !AARCH64 +}; + +CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg, (-1)); + +#ifdef AARCH64 + +CONSTANT_REGISTER_DECLARATION(FloatRegister, V0, ( 0)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V1, ( 1)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V2, ( 2)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V3, ( 3)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V4, ( 4)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V5, ( 5)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V6, ( 6)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V7, ( 7)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V8, ( 8)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V9, ( 9)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V10, (10)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V11, (11)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V12, (12)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V13, (13)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V14, (14)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V15, (15)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V16, (16)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V17, (17)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V18, (18)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V19, (19)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V20, (20)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V21, (21)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V22, (22)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V23, (23)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V24, (24)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V25, (25)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V26, (26)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V27, (27)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V28, (28)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V29, (29)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V30, (30)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, V31, (31)); + +#define S0 V0 +#define S1_reg V1 +#define Stemp V31 + +#define D0 V0 +#define D1 V1 + +#else // AARCH64 + +/* + * S1-S6 are named with "_reg" suffix to avoid conflict with + * constants defined in sharedRuntimeTrig.cpp + */ +CONSTANT_REGISTER_DECLARATION(FloatRegister, S0, ( 0)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S1_reg, ( 1)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S2_reg, ( 2)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S3_reg, ( 3)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S4_reg, ( 4)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S5_reg, ( 5)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S6_reg, ( 6)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S7, ( 7)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S8, ( 8)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S9, ( 9)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S10, (10)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S11, (11)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S12, (12)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S13, (13)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S14, (14)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S15, (15)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S16, (16)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S17, (17)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S18, (18)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S19, (19)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S20, (20)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S21, (21)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S22, (22)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S23, (23)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S24, (24)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S25, (25)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S26, (26)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S27, (27)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S28, (28)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S29, (29)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S30, (30)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, S31, (31)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, Stemp, (30)); + +CONSTANT_REGISTER_DECLARATION(FloatRegister, D0, ( 0)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D1, ( 2)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D2, ( 4)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D3, ( 6)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D4, ( 8)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D5, ( 10)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D6, ( 12)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D7, ( 14)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D8, ( 16)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D9, ( 18)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D10, ( 20)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D11, ( 22)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D12, ( 24)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D13, ( 26)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D14, ( 28)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D15, (30)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D16, (32)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D17, (34)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D18, (36)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D19, (38)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D20, (40)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D21, (42)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D22, (44)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D23, (46)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D24, (48)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D25, (50)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D26, (52)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D27, (54)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D28, (56)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D29, (58)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D30, (60)); +CONSTANT_REGISTER_DECLARATION(FloatRegister, D31, (62)); + +#endif // AARCH64 + +class ConcreteRegisterImpl : public AbstractRegisterImpl { + public: + enum { + log_vmregs_per_word = LogBytesPerWord - LogBytesPerInt, // VMRegs are of 4-byte size +#ifdef COMPILER2 + log_bytes_per_fpr = AARCH64_ONLY(4) NOT_AARCH64(2), // quad vectors +#else + log_bytes_per_fpr = AARCH64_ONLY(3) NOT_AARCH64(2), // double vectors +#endif + log_words_per_fpr = log_bytes_per_fpr - LogBytesPerWord, + words_per_fpr = 1 << log_words_per_fpr, + log_vmregs_per_fpr = log_bytes_per_fpr - LogBytesPerInt, + log_vmregs_per_gpr = log_vmregs_per_word, + vmregs_per_gpr = 1 << log_vmregs_per_gpr, + vmregs_per_fpr = 1 << log_vmregs_per_fpr, + + num_gpr = RegisterImpl::number_of_registers << log_vmregs_per_gpr, + max_gpr0 = num_gpr, + num_fpr = FloatRegisterImpl::number_of_registers << log_vmregs_per_fpr, + max_fpr0 = max_gpr0 + num_fpr, + number_of_registers = num_gpr + num_fpr + + // TODO-AARCH64 revise + 1+1 // APSR and FPSCR so that c2's REG_COUNT <= ConcreteRegisterImpl::number_of_registers + }; + + static const int max_gpr; + static const int max_fpr; +}; + +// TODO-AARCH64 revise the following definitions + +class VFPSystemRegisterImpl; +typedef VFPSystemRegisterImpl* VFPSystemRegister; +class VFPSystemRegisterImpl : public AbstractRegisterImpl { + public: + int encoding() const { return value(); } +}; + +#define FPSID ((VFPSystemRegister)0) +#define FPSCR ((VFPSystemRegister)1) +#define MVFR0 ((VFPSystemRegister)0x6) +#define MVFR1 ((VFPSystemRegister)0x7) + +/* + * Register definitions shared across interpreter and compiler + */ +#define Rexception_obj AARCH64_ONLY(R19) NOT_AARCH64(R4) +#define Rexception_pc AARCH64_ONLY(R20) NOT_AARCH64(R5) + +#ifdef AARCH64 +#define Rheap_base R27 +#endif // AARCH64 + +/* + * Interpreter register definitions common to C++ and template interpreters. + */ +#ifdef AARCH64 +#define Rlocals R23 +#define Rmethod R26 +#define Rthread R28 +#define Rtemp R16 +#define Rtemp2 R17 +#else +#define Rlocals R8 +#define Rmethod R9 +#define Rthread R10 +#define Rtemp R12 +#endif // AARCH64 + +// Interpreter calling conventions + +#define Rparams AARCH64_ONLY(R8) NOT_AARCH64(SP) +#define Rsender_sp AARCH64_ONLY(R19) NOT_AARCH64(R4) + +// JSR292 +// Note: R5_mh is needed only during the call setup, including adapters +// This does not seem to conflict with Rexception_pc +// In case of issues, R3 might be OK but adapters calling the runtime would have to save it +#define R5_mh R5 // MethodHandle register, used during the call setup +#define Rmh_SP_save FP // for C1 + +/* + * C++ Interpreter Register Defines + */ +#define Rsave0 R4 +#define Rsave1 R5 +#define Rsave2 R6 +#define Rstate altFP_7_11 // R7 or R11 +#define Ricklass R8 + +/* + * TemplateTable Interpreter Register Usage + */ + +// Temporary registers +#define R0_tmp R0 +#define R1_tmp R1 +#define R2_tmp R2 +#define R3_tmp R3 +#define R4_tmp R4 +#define R5_tmp R5 +#define R12_tmp R12 +#define LR_tmp LR + +#define S0_tmp S0 +#define S1_tmp S1_reg + +#define D0_tmp D0 +#define D1_tmp D1 + +// Temporary registers saved across VM calls (according to C calling conventions) +#define Rtmp_save0 AARCH64_ONLY(R19) NOT_AARCH64(R4) +#define Rtmp_save1 AARCH64_ONLY(R20) NOT_AARCH64(R5) + +// Cached TOS value +#define R0_tos R0 + +#ifndef AARCH64 +#define R0_tos_lo R0 +#define R1_tos_hi R1 +#endif + +#define S0_tos S0 +#define D0_tos D0 + +// Dispatch table +#define RdispatchTable AARCH64_ONLY(R22) NOT_AARCH64(R6) + +// Bytecode pointer +#define Rbcp AARCH64_ONLY(R24) NOT_AARCH64(altFP_7_11) + +// Pre-loaded next bytecode for the dispatch +#define R3_bytecode R3 + +// Conventions between bytecode templates and stubs +#define R2_ClassCastException_obj R2 +#define R4_ArrayIndexOutOfBounds_index R4 + +// Interpreter expression stack top +#define Rstack_top AARCH64_ONLY(R25) NOT_AARCH64(SP) + +/* + * Linux 32-bit ARM C ABI Register calling conventions + * + * REG use callee/caller saved + * + * R0 First argument reg caller + * result register + * R1 Second argument reg caller + * result register + * R2 Third argument reg caller + * R3 Fourth argument reg caller + * + * R4 - R8 Local variable registers callee + * R9 + * R10, R11 Local variable registers callee + * + * R12 (IP) Scratch register used in inter-procedural calling + * R13 (SP) Stack Pointer callee + * R14 (LR) Link register + * R15 (PC) Program Counter + * + * TODO-AARCH64: document AArch64 ABI + * + */ +#define c_rarg0 R0 +#define c_rarg1 R1 +#define c_rarg2 R2 +#define c_rarg3 R3 + +#ifdef AARCH64 +#define c_rarg4 R4 +#define c_rarg5 R5 +#define c_rarg6 R6 +#define c_rarg7 R7 +#endif + +#ifdef AARCH64 +#define GPR_PARAMS 8 +#define FPR_PARAMS 8 +#else +#define GPR_PARAMS 4 +#endif + + +// Java ABI +// XXX Is this correct? +#define j_rarg0 c_rarg0 +#define j_rarg1 c_rarg1 +#define j_rarg2 c_rarg2 +#define j_rarg3 c_rarg3 + +#ifdef AARCH64 +#define j_rarg4 c_rarg4 +#define j_rarg5 c_rarg5 +#define j_rarg6 c_rarg6 +#define j_rarg7 c_rarg7 +#endif + +#endif // CPU_ARM_VM_REGISTER_ARM_HPP