mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-29 08:05:14 +00:00
8289046: Undefined Behaviour in x86 class Assembler
Reviewed-by: shade, kvn
This commit is contained in:
parent
d61c0c79cf
commit
86ef7b20eb
@ -534,18 +534,25 @@ static bool is_valid_encoding(int reg_enc) {
|
||||
|
||||
static int raw_encode(Register reg) {
|
||||
assert(reg == noreg || reg->is_valid(), "sanity");
|
||||
int reg_enc = (intptr_t)reg;
|
||||
int reg_enc = reg->raw_encoding();
|
||||
assert(reg_enc == -1 || is_valid_encoding(reg_enc), "sanity");
|
||||
return reg_enc;
|
||||
}
|
||||
|
||||
static int raw_encode(XMMRegister xmmreg) {
|
||||
assert(xmmreg == xnoreg || xmmreg->is_valid(), "sanity");
|
||||
int xmmreg_enc = (intptr_t)xmmreg;
|
||||
int xmmreg_enc = xmmreg->raw_encoding();
|
||||
assert(xmmreg_enc == -1 || is_valid_encoding(xmmreg_enc), "sanity");
|
||||
return xmmreg_enc;
|
||||
}
|
||||
|
||||
static int raw_encode(KRegister kreg) {
|
||||
assert(kreg == knoreg || kreg->is_valid(), "sanity");
|
||||
int kreg_enc = kreg->raw_encoding();
|
||||
assert(kreg_enc == -1 || is_valid_encoding(kreg_enc), "sanity");
|
||||
return kreg_enc;
|
||||
}
|
||||
|
||||
static int modrm_encoding(int mod, int dst_enc, int src_enc) {
|
||||
return (mod & 3) << 6 | (dst_enc & 7) << 3 | (src_enc & 7);
|
||||
}
|
||||
@ -719,6 +726,22 @@ void Assembler::emit_operand(XMMRegister xmmreg, Register base, XMMRegister xmmi
|
||||
scale, disp, rspec, /* rip_relative_correction */ 0);
|
||||
}
|
||||
|
||||
void Assembler::emit_operand(KRegister kreg, Address adr,
|
||||
int rip_relative_correction) {
|
||||
emit_operand(kreg, adr._base, adr._index, adr._scale, adr._disp,
|
||||
adr._rspec,
|
||||
rip_relative_correction);
|
||||
}
|
||||
|
||||
void Assembler::emit_operand(KRegister kreg, Register base, Register index,
|
||||
Address::ScaleFactor scale, int disp,
|
||||
RelocationHolder const& rspec,
|
||||
int rip_relative_correction) {
|
||||
assert(!index->is_valid() || index != rsp, "illegal addressing mode");
|
||||
emit_operand_helper(raw_encode(kreg), raw_encode(base), raw_encode(index),
|
||||
scale, disp, rspec, rip_relative_correction);
|
||||
}
|
||||
|
||||
// Secret local extension to Assembler::WhichOperand:
|
||||
#define end_pc_operand (_WhichOperand_limit)
|
||||
|
||||
@ -2589,7 +2612,7 @@ void Assembler::kmovwl(KRegister dst, Address src) {
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0x90);
|
||||
emit_operand((Register)dst, src);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::kmovwl(Address dst, KRegister src) {
|
||||
@ -2598,7 +2621,7 @@ void Assembler::kmovwl(Address dst, KRegister src) {
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0x91);
|
||||
emit_operand((Register)src, dst);
|
||||
emit_operand(src, dst);
|
||||
}
|
||||
|
||||
void Assembler::kmovwl(KRegister dst, KRegister src) {
|
||||
@ -2635,7 +2658,7 @@ void Assembler::kmovql(KRegister dst, Address src) {
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0x90);
|
||||
emit_operand((Register)dst, src);
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::kmovql(Address dst, KRegister src) {
|
||||
@ -2644,7 +2667,7 @@ void Assembler::kmovql(Address dst, KRegister src) {
|
||||
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(dst, 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
|
||||
emit_int8((unsigned char)0x91);
|
||||
emit_operand((Register)src, dst);
|
||||
emit_operand(src, dst);
|
||||
}
|
||||
|
||||
void Assembler::kmovql(KRegister dst, Register src) {
|
||||
|
||||
@ -781,6 +781,21 @@ private:
|
||||
int disp,
|
||||
RelocationHolder const& rspec);
|
||||
|
||||
void emit_operand_helper(KRegister kreg,
|
||||
int base_enc, int index_enc, Address::ScaleFactor scale,
|
||||
int disp,
|
||||
RelocationHolder const& rspec,
|
||||
int rip_relative_correction = 0);
|
||||
|
||||
void emit_operand(KRegister kreg, Address adr,
|
||||
int rip_relative_correction = 0);
|
||||
|
||||
void emit_operand(KRegister kreg,
|
||||
Register base, Register index, Address::ScaleFactor scale,
|
||||
int disp,
|
||||
RelocationHolder const& rspec,
|
||||
int rip_relative_correction = 0);
|
||||
|
||||
void emit_operand(XMMRegister reg, Address adr);
|
||||
|
||||
// Immediate-to-memory forms
|
||||
|
||||
@ -77,4 +77,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
#define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false
|
||||
#endif
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
#endif // CPU_X86_GLOBALDEFINITIONS_X86_HPP
|
||||
|
||||
@ -783,7 +783,7 @@ void MacroAssembler::avx_ghash(Register input_state, Register htbl,
|
||||
void MacroAssembler::aesctr_encrypt(Register src_addr, Register dest_addr, Register key, Register counter,
|
||||
Register len_reg, Register used, Register used_addr, Register saved_encCounter_start) {
|
||||
|
||||
const Register rounds = 0;
|
||||
const Register rounds = rax;
|
||||
const Register pos = r12;
|
||||
|
||||
Label PRELOOP_START, EXIT_PRELOOP, REMAINDER, REMAINDER_16, LOOP, END, EXIT, END_LOOP,
|
||||
|
||||
@ -26,6 +26,11 @@
|
||||
|
||||
#include "register_x86.hpp"
|
||||
|
||||
REGISTER_IMPL_DEFINITION(Register, RegisterImpl, RegisterImpl::number_of_registers);
|
||||
REGISTER_IMPL_DEFINITION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
REGISTER_IMPL_DEFINITION(XMMRegister, XMMRegisterImpl, XMMRegisterImpl::number_of_registers);
|
||||
REGISTER_IMPL_DEFINITION(KRegister, KRegisterImpl, KRegisterImpl::number_of_registers);
|
||||
|
||||
#ifndef AMD64
|
||||
const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers;
|
||||
#else
|
||||
@ -40,7 +45,7 @@ const int ConcreteRegisterImpl::max_kpr = ConcreteRegisterImpl::max_xmm +
|
||||
KRegisterImpl::max_slots_per_register * KRegisterImpl::number_of_registers;
|
||||
|
||||
const char* RegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
#ifndef AMD64
|
||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
||||
#else
|
||||
@ -52,14 +57,14 @@ const char* RegisterImpl::name() const {
|
||||
}
|
||||
|
||||
const char* FloatRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "noreg";
|
||||
}
|
||||
|
||||
const char* XMMRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7"
|
||||
#ifdef AMD64
|
||||
,"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
|
||||
|
||||
@ -37,14 +37,14 @@ typedef VMRegImpl* VMReg;
|
||||
class RegisterImpl;
|
||||
typedef RegisterImpl* Register;
|
||||
|
||||
|
||||
// The implementation of integer registers for the ia32 architecture
|
||||
inline 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 {
|
||||
#ifndef AMD64
|
||||
number_of_registers = 8,
|
||||
@ -61,17 +61,20 @@ class RegisterImpl: public AbstractRegisterImpl {
|
||||
Register successor() const { return as_Register(encoding() + 1); }
|
||||
|
||||
// construction
|
||||
inline friend Register as_Register(int encoding);
|
||||
inline constexpr friend Register as_Register(int encoding);
|
||||
|
||||
inline VMReg as_VMReg();
|
||||
inline 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; }
|
||||
const char* name() const;
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
bool has_byte_register() const { return 0 <= raw_encoding() && raw_encoding() < number_of_byte_registers; }
|
||||
const char *name() const;
|
||||
};
|
||||
|
||||
REGISTER_IMPL_DECLARATION(Register, RegisterImpl, RegisterImpl::number_of_registers);
|
||||
|
||||
// The integer registers of the ia32/amd64 architecture
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
|
||||
@ -98,48 +101,50 @@ CONSTANT_REGISTER_DECLARATION(Register, r15, (15));
|
||||
|
||||
// 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 ia32 architecture
|
||||
class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
public:
|
||||
static constexpr FloatRegister first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 8
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend FloatRegister as_FloatRegister(int encoding);
|
||||
inline friend constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
inline VMReg as_VMReg();
|
||||
inline VMReg as_VMReg() const;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
|
||||
FloatRegister successor() const { return as_FloatRegister(encoding() + 1); }
|
||||
|
||||
// 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; }
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
const char* name() const;
|
||||
|
||||
};
|
||||
|
||||
REGISTER_IMPL_DECLARATION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg, (-1));
|
||||
|
||||
// Use XMMRegister as shortcut
|
||||
class XMMRegisterImpl;
|
||||
typedef XMMRegisterImpl* XMMRegister;
|
||||
|
||||
inline XMMRegister as_XMMRegister(int encoding) {
|
||||
return (XMMRegister)(intptr_t)encoding;
|
||||
}
|
||||
|
||||
inline constexpr XMMRegister as_XMMRegister(int encoding);
|
||||
|
||||
// The implementation of XMM registers.
|
||||
class XMMRegisterImpl: public AbstractRegisterImpl {
|
||||
static constexpr XMMRegister first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
#ifndef AMD64
|
||||
@ -152,16 +157,17 @@ class XMMRegisterImpl: public AbstractRegisterImpl {
|
||||
};
|
||||
|
||||
// construction
|
||||
friend XMMRegister as_XMMRegister(int encoding);
|
||||
friend constexpr XMMRegister as_XMMRegister(int encoding);
|
||||
|
||||
inline VMReg as_VMReg();
|
||||
inline VMReg as_VMReg() const;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
XMMRegister successor() const { return as_XMMRegister(encoding() + 1); }
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register (%d)", (int)(intptr_t)this ); return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
const char* name() const;
|
||||
const char* sub_word_name(int offset) const;
|
||||
|
||||
@ -179,6 +185,8 @@ class XMMRegisterImpl: public AbstractRegisterImpl {
|
||||
};
|
||||
|
||||
|
||||
REGISTER_IMPL_DECLARATION(XMMRegister, XMMRegisterImpl, XMMRegisterImpl::number_of_registers);
|
||||
|
||||
// The XMM registers, for P3 and up chips
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xnoreg , (-1));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm0 , ( 0));
|
||||
@ -220,12 +228,12 @@ CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm31, (31));
|
||||
class KRegisterImpl;
|
||||
typedef KRegisterImpl* KRegister;
|
||||
|
||||
inline KRegister as_KRegister(int encoding) {
|
||||
return (KRegister)(intptr_t)encoding;
|
||||
}
|
||||
inline constexpr KRegister as_KRegister(int encoding);
|
||||
|
||||
// The implementation of AVX-3 (AVX-512) opmask registers.
|
||||
class KRegisterImpl : public AbstractRegisterImpl {
|
||||
static constexpr KRegister first();
|
||||
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 8,
|
||||
@ -235,19 +243,22 @@ public:
|
||||
};
|
||||
|
||||
// construction
|
||||
friend KRegister as_KRegister(int encoding);
|
||||
friend constexpr KRegister as_KRegister(int encoding);
|
||||
|
||||
inline VMReg as_VMReg();
|
||||
inline VMReg as_VMReg() const;
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
KRegister successor() const { return as_KRegister(encoding() + 1); }
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register (%d)", (int)(intptr_t)this); return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
int raw_encoding() const { return this - first(); }
|
||||
int encoding() const { assert(is_valid(), "invalid register (%d)", (int)raw_encoding()); return raw_encoding(); }
|
||||
bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
REGISTER_IMPL_DECLARATION(KRegister, KRegisterImpl, KRegisterImpl::number_of_registers);
|
||||
|
||||
// The Mask registers, for AVX3 enabled and up chips
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, knoreg, (-1));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k0, (0));
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#ifndef CPU_X86_VMREG_X86_INLINE_HPP
|
||||
#define CPU_X86_VMREG_X86_INLINE_HPP
|
||||
|
||||
inline VMReg RegisterImpl::as_VMReg() {
|
||||
inline VMReg RegisterImpl::as_VMReg() const {
|
||||
if( this==noreg ) return VMRegImpl::Bad();
|
||||
#ifdef AMD64
|
||||
return VMRegImpl::as_VMReg(encoding() << 1 );
|
||||
@ -34,15 +34,15 @@ inline VMReg RegisterImpl::as_VMReg() {
|
||||
#endif // AMD64
|
||||
}
|
||||
|
||||
inline VMReg FloatRegisterImpl::as_VMReg() {
|
||||
inline VMReg FloatRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_gpr);
|
||||
}
|
||||
|
||||
inline VMReg XMMRegisterImpl::as_VMReg() {
|
||||
inline VMReg XMMRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() << 4) + ConcreteRegisterImpl::max_fpr);
|
||||
}
|
||||
|
||||
inline VMReg KRegisterImpl::as_VMReg() {
|
||||
inline VMReg KRegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_xmm);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user