8276563: Undefined Behaviour in class Assembler
Reviewed-by: jvernee, stuefe
This commit is contained in:
parent
d175d33f44
commit
64c0c0e109
@ -1726,7 +1726,7 @@ void mvnw(Register Rd, Register Rm,
|
||||
|
||||
#define INSN(NAME, op) \
|
||||
void NAME(Register Rn, Register Rm, int imm, Condition cond) { \
|
||||
int regNumber = (Rm == zr ? 31 : (uintptr_t)Rm); \
|
||||
int regNumber = (Rm == zr ? 31 : Rm->encoding()); \
|
||||
conditional_compare(op, 0, 0, 0, Rn, regNumber, imm, cond); \
|
||||
} \
|
||||
\
|
||||
|
@ -45,7 +45,7 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const {
|
||||
const ABIDescriptor ForeignGlobals::parse_abi_descriptor_impl(jobject jabi) const {
|
||||
oop abi_oop = JNIHandles::resolve_non_null(jabi);
|
||||
ABIDescriptor abi;
|
||||
const Register (*to_Register)(int) = as_Register;
|
||||
constexpr Register (*to_Register)(int) = as_Register;
|
||||
|
||||
objArrayOop inputStorage = cast<objArrayOop>(abi_oop->obj_field(ABI.inputStorage_offset));
|
||||
loadArray(inputStorage, INTEGER_TYPE, abi._integer_argument_registers, to_Register);
|
||||
|
@ -67,4 +67,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
#define NOT_R18_RESERVED(code) code
|
||||
#endif
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
#endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP
|
||||
|
@ -186,7 +186,7 @@ VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
|
||||
if (jvmci_reg < RegisterImpl::number_of_registers) {
|
||||
return as_Register(jvmci_reg)->as_VMReg();
|
||||
} else {
|
||||
jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers_for_jvmci;
|
||||
jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_declared_registers;
|
||||
if (floatRegisterNumber >= 0 && floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
|
||||
return as_FloatRegister(floatRegisterNumber)->as_VMReg();
|
||||
}
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "register_aarch64.hpp"
|
||||
|
||||
REGISTER_IMPL_DEFINITION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers);
|
||||
REGISTER_IMPL_DEFINITION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
REGISTER_IMPL_DEFINITION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers);
|
||||
|
||||
const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers *
|
||||
RegisterImpl::max_slots_per_register;
|
||||
|
||||
@ -38,7 +42,7 @@ const int ConcreteRegisterImpl::max_pr
|
||||
PRegisterImpl::number_of_registers * PRegisterImpl::max_slots_per_register;
|
||||
|
||||
const char* RegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
|
||||
"rscratch1", "rscratch2",
|
||||
"r10", "r11", "r12", "r13", "r14", "r15", "r16",
|
||||
@ -50,7 +54,7 @@ const char* RegisterImpl::name() const {
|
||||
}
|
||||
|
||||
const char* FloatRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
||||
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
||||
@ -60,7 +64,7 @@ const char* FloatRegisterImpl::name() const {
|
||||
}
|
||||
|
||||
const char* PRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15"
|
||||
};
|
||||
|
@ -34,42 +34,42 @@ typedef VMRegImpl* VMReg;
|
||||
|
||||
// Use Register as shortcut
|
||||
class RegisterImpl;
|
||||
typedef RegisterImpl* Register;
|
||||
typedef const RegisterImpl* Register;
|
||||
|
||||
inline const Register as_Register(int encoding) {
|
||||
return (Register)(intptr_t) encoding;
|
||||
}
|
||||
inline constexpr Register as_Register(int encoding);
|
||||
|
||||
class RegisterImpl: public AbstractRegisterImpl {
|
||||
public:
|
||||
static constexpr Register first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 32,
|
||||
number_of_byte_registers = 32,
|
||||
number_of_registers_for_jvmci = 34, // Including SP and ZR.
|
||||
number_of_declared_registers = 34, // Including SP and ZR.
|
||||
max_slots_per_register = 2
|
||||
};
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
Register successor() const { return as_Register(encoding() + 1); }
|
||||
const Register successor() const { return this + 1; }
|
||||
|
||||
// construction
|
||||
inline friend const Register as_Register(int encoding);
|
||||
inline friend constexpr Register as_Register(int encoding);
|
||||
|
||||
VMReg as_VMReg();
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
bool has_byte_register() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
const char* name() const;
|
||||
int encoding_nocheck() const { return (intptr_t)this; }
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
};
|
||||
|
||||
|
||||
REGISTER_IMPL_DECLARATION(Register, RegisterImpl, RegisterImpl::number_of_declared_registers);
|
||||
|
||||
// The integer registers of the aarch64 architecture
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
|
||||
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r0, (0));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r1, (1));
|
||||
CONSTANT_REGISTER_DECLARATION(Register, r2, (2));
|
||||
@ -126,15 +126,15 @@ const Register dummy_reg = r31_sp;
|
||||
|
||||
// Use FloatRegister as shortcut
|
||||
class FloatRegisterImpl;
|
||||
typedef FloatRegisterImpl* FloatRegister;
|
||||
typedef const FloatRegisterImpl* FloatRegister;
|
||||
|
||||
inline FloatRegister as_FloatRegister(int encoding) {
|
||||
return (FloatRegister)(intptr_t) encoding;
|
||||
}
|
||||
inline constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
// The implementation of floating point registers for the architecture
|
||||
class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
public:
|
||||
static constexpr FloatRegister first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 32,
|
||||
max_slots_per_register = 8,
|
||||
@ -144,21 +144,25 @@ class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend FloatRegister as_FloatRegister(int encoding);
|
||||
inline friend constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
VMReg as_VMReg();
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
FloatRegister successor() const { return as_FloatRegister((encoding() + 1) % 32); }
|
||||
FloatRegister successor() const {
|
||||
return as_FloatRegister((encoding() + 1) % (unsigned)number_of_registers);
|
||||
}
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; }
|
||||
int encoding_nocheck() const { return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
const char* name() const;
|
||||
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
};
|
||||
|
||||
REGISTER_IMPL_DECLARATION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
|
||||
|
||||
// The float registers of the AARCH64 architecture
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
|
||||
@ -232,13 +236,13 @@ CONSTANT_REGISTER_DECLARATION(FloatRegister, z31 , (31));
|
||||
|
||||
|
||||
class PRegisterImpl;
|
||||
typedef PRegisterImpl* PRegister;
|
||||
inline PRegister as_PRegister(int encoding) {
|
||||
return (PRegister)(intptr_t)encoding;
|
||||
}
|
||||
typedef const PRegisterImpl* PRegister;
|
||||
inline constexpr PRegister as_PRegister(int encoding);
|
||||
|
||||
// The implementation of predicate registers for the architecture
|
||||
class PRegisterImpl: public AbstractRegisterImpl {
|
||||
static constexpr PRegister first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 16,
|
||||
@ -252,21 +256,24 @@ class PRegisterImpl: public AbstractRegisterImpl {
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend PRegister as_PRegister(int encoding);
|
||||
inline friend constexpr PRegister as_PRegister(int encoding);
|
||||
|
||||
VMReg as_VMReg();
|
||||
VMReg as_VMReg() const;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
PRegister successor() const { return as_PRegister(encoding() + 1); }
|
||||
PRegister successor() const { return this + 1; }
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return (intptr_t)this; }
|
||||
int encoding_nocheck() const { return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
bool is_governing() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_governing_registers; }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
|
||||
int encoding_nocheck() const { return this - first(); }
|
||||
bool is_valid() const { return (unsigned)encoding_nocheck() < number_of_registers; }
|
||||
bool is_governing() const { return first() <= this && this - first() < number_of_governing_registers; }
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
|
||||
REGISTER_IMPL_DECLARATION(PRegister, PRegisterImpl, PRegisterImpl::number_of_registers);
|
||||
|
||||
// The predicate registers of SVE.
|
||||
CONSTANT_REGISTER_DECLARATION(PRegister, pnoreg, (-1));
|
||||
|
||||
|
@ -26,17 +26,17 @@
|
||||
#ifndef CPU_AARCH64_VMREG_AARCH64_INLINE_HPP
|
||||
#define CPU_AARCH64_VMREG_AARCH64_INLINE_HPP
|
||||
|
||||
inline VMReg RegisterImpl::as_VMReg() {
|
||||
inline VMReg RegisterImpl::as_VMReg() const {
|
||||
if( this==noreg ) return VMRegImpl::Bad();
|
||||
return VMRegImpl::as_VMReg(encoding() * RegisterImpl::max_slots_per_register);
|
||||
}
|
||||
|
||||
inline VMReg FloatRegisterImpl::as_VMReg() {
|
||||
inline VMReg FloatRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() * FloatRegisterImpl::max_slots_per_register) +
|
||||
ConcreteRegisterImpl::max_gpr);
|
||||
}
|
||||
|
||||
inline VMReg PRegisterImpl::as_VMReg() {
|
||||
inline VMReg PRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_fpr);
|
||||
}
|
||||
|
||||
|
@ -45,15 +45,48 @@ class AbstractRegisterImpl {
|
||||
int value() const { return (int)(intx)this; }
|
||||
};
|
||||
|
||||
|
||||
// Macros to help define all kinds of registers
|
||||
|
||||
#ifndef USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
#define AS_REGISTER(type,name) ((type)name##_##type##EnumValue)
|
||||
|
||||
#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
|
||||
const type name = ((type)value); \
|
||||
#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
|
||||
const type name = ((type)value); \
|
||||
enum { name##_##type##EnumValue = (value) }
|
||||
|
||||
#define REGISTER_DECLARATION(type, name, value) \
|
||||
#else // USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
#define REGISTER_IMPL_DECLARATION(type, impl_type, reg_count) \
|
||||
inline constexpr type as_ ## type(int encoding) { \
|
||||
return impl_type::first() + encoding; \
|
||||
} \
|
||||
extern impl_type all_ ## type ## s[reg_count + 1] INTERNAL_VISIBILITY; \
|
||||
inline constexpr type impl_type::first() { return all_ ## type ## s + 1; }
|
||||
|
||||
#define REGISTER_IMPL_DEFINITION(type, impl_type, reg_count) \
|
||||
impl_type all_ ## type ## s[reg_count + 1];
|
||||
|
||||
#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
|
||||
constexpr type name = as_ ## type(value);
|
||||
|
||||
#endif // USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
|
||||
#define REGISTER_DECLARATION(type, name, value) \
|
||||
const type name = ((type)value)
|
||||
|
||||
|
||||
// For definitions of RegisterImpl* instances. To be redefined in an
|
||||
// OS-specific way.
|
||||
#ifdef __GNUC__
|
||||
#define INTERNAL_VISIBILITY __attribute__ ((visibility ("internal")))
|
||||
#else
|
||||
#define INTERNAL_VISIBILITY
|
||||
#endif
|
||||
|
||||
|
||||
#define REGISTER_DEFINITION(type, name)
|
||||
|
||||
#include CPU_HEADER(register)
|
||||
|
Loading…
x
Reference in New Issue
Block a user