8328998: Encoding support for Intel APX extended general-purpose registers
Reviewed-by: kvn, sviswanathan, jbhateja
This commit is contained in:
parent
ddd73b4583
commit
f8a3e4e428
File diff suppressed because it is too large
Load Diff
@ -308,17 +308,29 @@ class Address {
|
||||
|
||||
private:
|
||||
bool base_needs_rex() const {
|
||||
return _base->is_valid() && _base->encoding() >= 8;
|
||||
return _base->is_valid() && ((_base->encoding() & 8) == 8);
|
||||
}
|
||||
|
||||
bool base_needs_rex2() const {
|
||||
return _base->is_valid() && _base->encoding() >= 16;
|
||||
}
|
||||
|
||||
bool index_needs_rex() const {
|
||||
return _index->is_valid() &&_index->encoding() >= 8;
|
||||
return _index->is_valid() && ((_index->encoding() & 8) == 8);
|
||||
}
|
||||
|
||||
bool index_needs_rex2() const {
|
||||
return _index->is_valid() &&_index->encoding() >= 16;
|
||||
}
|
||||
|
||||
bool xmmindex_needs_rex() const {
|
||||
return _xmmindex->is_valid() && ((_xmmindex->encoding() & 8) == 8);
|
||||
}
|
||||
|
||||
bool xmmindex_needs_rex2() const {
|
||||
return _xmmindex->is_valid() && _xmmindex->encoding() >= 16;
|
||||
}
|
||||
|
||||
relocInfo::relocType reloc() const { return _rspec.type(); }
|
||||
|
||||
friend class Assembler;
|
||||
@ -508,12 +520,26 @@ class Assembler : public AbstractAssembler {
|
||||
REX_WRX = 0x4E,
|
||||
REX_WRXB = 0x4F,
|
||||
|
||||
REX2 = 0xd5,
|
||||
WREX2 = REX2 << 8,
|
||||
|
||||
VEX_3bytes = 0xC4,
|
||||
VEX_2bytes = 0xC5,
|
||||
EVEX_4bytes = 0x62,
|
||||
Prefix_EMPTY = 0x0
|
||||
};
|
||||
|
||||
enum PrefixBits {
|
||||
REXBIT_B = 0x01,
|
||||
REXBIT_X = 0x02,
|
||||
REXBIT_R = 0x04,
|
||||
REXBIT_W = 0x08,
|
||||
REX2BIT_B4 = 0x10,
|
||||
REX2BIT_X4 = 0x20,
|
||||
REX2BIT_R4 = 0x40,
|
||||
REX2BIT_M0 = 0x80
|
||||
};
|
||||
|
||||
enum VexPrefix {
|
||||
VEX_B = 0x20,
|
||||
VEX_X = 0x40,
|
||||
@ -525,10 +551,18 @@ class Assembler : public AbstractAssembler {
|
||||
EVEX_F = 0x04,
|
||||
EVEX_V = 0x08,
|
||||
EVEX_Rb = 0x10,
|
||||
EVEX_B = 0x20,
|
||||
EVEX_X = 0x40,
|
||||
EVEX_Z = 0x80
|
||||
};
|
||||
|
||||
enum ExtEvexPrefix {
|
||||
EEVEX_R = 0x10,
|
||||
EEVEX_B = 0x08,
|
||||
EEVEX_X = 0x04,
|
||||
EEVEX_V = 0x08
|
||||
};
|
||||
|
||||
enum EvexRoundPrefix {
|
||||
EVEX_RNE = 0x0,
|
||||
EVEX_RD = 0x1,
|
||||
@ -540,7 +574,7 @@ class Assembler : public AbstractAssembler {
|
||||
VEX_SIMD_NONE = 0x0,
|
||||
VEX_SIMD_66 = 0x1,
|
||||
VEX_SIMD_F3 = 0x2,
|
||||
VEX_SIMD_F2 = 0x3
|
||||
VEX_SIMD_F2 = 0x3,
|
||||
};
|
||||
|
||||
enum VexOpcode {
|
||||
@ -548,6 +582,7 @@ class Assembler : public AbstractAssembler {
|
||||
VEX_OPCODE_0F = 0x1,
|
||||
VEX_OPCODE_0F_38 = 0x2,
|
||||
VEX_OPCODE_0F_3A = 0x3,
|
||||
VEX_OPCODE_0F_3C = 0x4,
|
||||
VEX_OPCODE_MASK = 0x1F
|
||||
};
|
||||
|
||||
@ -572,7 +607,8 @@ class Assembler : public AbstractAssembler {
|
||||
EVEX_OVM = 20,
|
||||
EVEX_M128 = 21,
|
||||
EVEX_DUP = 22,
|
||||
EVEX_ETUP = 23
|
||||
EVEX_NOSCALE = 23,
|
||||
EVEX_ETUP = 24
|
||||
};
|
||||
|
||||
enum EvexInputSizeInBits {
|
||||
@ -686,33 +722,62 @@ private:
|
||||
InstructionAttr *_attributes;
|
||||
void set_attributes(InstructionAttr* attributes);
|
||||
|
||||
int get_base_prefix_bits(int enc);
|
||||
int get_index_prefix_bits(int enc);
|
||||
int get_base_prefix_bits(Register base);
|
||||
int get_index_prefix_bits(Register index);
|
||||
int get_reg_prefix_bits(int enc);
|
||||
|
||||
// 64bit prefixes
|
||||
void prefix(Register reg);
|
||||
void prefix(Register dst, Register src, Prefix p);
|
||||
void prefix_rex2(Register dst, Register src);
|
||||
void prefix(Register dst, Address adr, Prefix p);
|
||||
void prefix_rex2(Register dst, Address adr);
|
||||
|
||||
void prefix(Address adr);
|
||||
void prefix(Address adr, Register reg, bool byteinst = false);
|
||||
// The is_map1 bool indicates an x86 map1 instruction which, when
|
||||
// legacy encoded, uses a 0x0F opcode prefix. By specification, the
|
||||
// opcode prefix is omitted when using rex2 encoding in support
|
||||
// of APX extended GPRs.
|
||||
void prefix(Address adr, bool is_map1 = false);
|
||||
void prefix_rex2(Address adr, bool is_map1 = false);
|
||||
void prefix(Address adr, Register reg, bool byteinst = false, bool is_map1 = false);
|
||||
void prefix_rex2(Address adr, Register reg, bool byteinst = false, bool is_map1 = false);
|
||||
void prefix(Address adr, XMMRegister reg);
|
||||
void prefix_rex2(Address adr, XMMRegister reg);
|
||||
|
||||
int prefix_and_encode(int reg_enc, bool byteinst = false);
|
||||
int prefix_and_encode(int dst_enc, int src_enc) {
|
||||
return prefix_and_encode(dst_enc, false, src_enc, false);
|
||||
int prefix_and_encode(int reg_enc, bool byteinst = false, bool is_map1 = false);
|
||||
int prefix_and_encode_rex2(int reg_enc, bool is_map1 = false);
|
||||
int prefix_and_encode(int dst_enc, int src_enc, bool is_map1 = false) {
|
||||
return prefix_and_encode(dst_enc, false, src_enc, false, is_map1);
|
||||
}
|
||||
int prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte);
|
||||
int prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte, bool is_map1 = false);
|
||||
|
||||
int prefix_and_encode_rex2(int dst_enc, int src_enc, int init_bits = 0);
|
||||
// Some prefixq variants always emit exactly one prefix byte, so besides a
|
||||
// prefix-emitting method we provide a method to get the prefix byte to emit,
|
||||
// which can then be folded into a byte stream.
|
||||
int8_t get_prefixq(Address adr);
|
||||
int8_t get_prefixq(Address adr, Register reg);
|
||||
int get_prefixq(Address adr, bool is_map1 = false);
|
||||
int get_prefixq_rex2(Address adr, bool is_map1 = false);
|
||||
int get_prefixq(Address adr, Register reg, bool is_map1 = false);
|
||||
int get_prefixq_rex2(Address adr, Register reg, bool ismap1 = false);
|
||||
|
||||
void prefixq(Address adr);
|
||||
void prefixq(Address adr, Register reg);
|
||||
void prefixq(Address adr, Register reg, bool is_map1 = false);
|
||||
void prefixq(Address adr, XMMRegister reg);
|
||||
void prefixq_rex2(Address adr, XMMRegister src);
|
||||
|
||||
int prefixq_and_encode(int reg_enc);
|
||||
int prefixq_and_encode(int dst_enc, int src_enc);
|
||||
bool prefix_is_rex2(int prefix);
|
||||
|
||||
int prefixq_and_encode(int reg_enc, bool is_map1 = false);
|
||||
int prefixq_and_encode_rex2(int reg_enc, bool is_map1 = false);
|
||||
int prefixq_and_encode(int dst_enc, int src_enc, bool is_map1 = false);
|
||||
int prefixq_and_encode_rex2(int dst_enc, int src_enc, bool is_map1 = false);
|
||||
|
||||
bool needs_rex2(Register reg1, Register reg2 = noreg, Register reg3 = noreg);
|
||||
|
||||
bool needs_eevex(Register reg1, Register reg2 = noreg, Register reg3 = noreg);
|
||||
bool needs_eevex(int enc1, int enc2 = -1, int enc3 = -1);
|
||||
|
||||
void rex_prefix(Address adr, XMMRegister xreg,
|
||||
VexSimdPrefix pre, VexOpcode opc, bool rex_w);
|
||||
@ -721,22 +786,21 @@ private:
|
||||
|
||||
void vex_prefix(bool vex_r, bool vex_b, bool vex_x, int nds_enc, VexSimdPrefix pre, VexOpcode opc);
|
||||
|
||||
void evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_r, bool evex_v,
|
||||
int nds_enc, VexSimdPrefix pre, VexOpcode opc);
|
||||
void evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool evex_v, bool evex_r, bool evex_b,
|
||||
bool eevex_x, int nds_enc, VexSimdPrefix pre, VexOpcode opc);
|
||||
|
||||
void vex_prefix(Address adr, int nds_enc, int xreg_enc,
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
void vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc,
|
||||
InstructionAttr *attributes);
|
||||
|
||||
int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
InstructionAttr *attributes);
|
||||
InstructionAttr *attributes, bool src_is_gpr = false);
|
||||
|
||||
void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre,
|
||||
VexOpcode opc, InstructionAttr *attributes);
|
||||
|
||||
int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src, VexSimdPrefix pre,
|
||||
VexOpcode opc, InstructionAttr *attributes);
|
||||
VexOpcode opc, InstructionAttr *attributes, bool src_is_gpr = false);
|
||||
|
||||
// Helper functions for groups of instructions
|
||||
void emit_arith_b(int op1, int op2, Register dst, int imm8);
|
||||
@ -821,6 +885,10 @@ private:
|
||||
void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
|
||||
void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
|
||||
|
||||
void emit_prefix_and_int8(int prefix, int b1);
|
||||
void emit_opcode_prefix_and_encoding(int byte1, int ocp_and_encoding);
|
||||
void emit_opcode_prefix_and_encoding(int byte1, int byte2, int ocp_and_encoding);
|
||||
void emit_opcode_prefix_and_encoding(int byte1, int byte2, int ocp_and_encoding, int byte3);
|
||||
bool always_reachable(AddressLiteral adr) NOT_LP64( { return true; } );
|
||||
bool reachable(AddressLiteral adr) NOT_LP64( { return true; } );
|
||||
|
||||
@ -907,6 +975,8 @@ private:
|
||||
// Instruction prefixes
|
||||
void prefix(Prefix p);
|
||||
|
||||
void prefix16(int p);
|
||||
|
||||
public:
|
||||
|
||||
// Creation
|
||||
|
@ -30,23 +30,53 @@
|
||||
#include "code/codeCache.hpp"
|
||||
|
||||
#ifndef _LP64
|
||||
inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { return reg_enc; }
|
||||
inline int Assembler::prefixq_and_encode(int reg_enc) { return reg_enc; }
|
||||
inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst, bool is_map1)
|
||||
{
|
||||
int opc_prefix = is_map1 ? 0x0F00 : 0;
|
||||
return opc_prefix | reg_enc;
|
||||
}
|
||||
|
||||
inline int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) { return dst_enc << 3 | src_enc; }
|
||||
inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { return dst_enc << 3 | src_enc; }
|
||||
inline int Assembler::prefixq_and_encode(int reg_enc, bool is_map1) {
|
||||
int opc_prefix = is_map1 ? 0xF00 : 0;
|
||||
return opc_prefix | reg_enc;
|
||||
}
|
||||
|
||||
inline int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte, bool is_map1) {
|
||||
int opc_prefix = is_map1 ? 0xF00 : 0;
|
||||
return opc_prefix | (dst_enc << 3 | src_enc);
|
||||
}
|
||||
|
||||
inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc, bool is_map1) {
|
||||
int opc_prefix = is_map1 ? 0xF00 : 0;
|
||||
return opc_prefix | dst_enc << 3 | src_enc;
|
||||
}
|
||||
|
||||
inline void Assembler::prefix(Register reg) {}
|
||||
inline void Assembler::prefix(Register dst, Register src, Prefix p) {}
|
||||
inline void Assembler::prefix(Register dst, Address adr, Prefix p) {}
|
||||
inline void Assembler::prefix(Address adr) {}
|
||||
|
||||
inline void Assembler::prefix(Address adr, bool is_map1) {
|
||||
if (is_map1) {
|
||||
emit_int8(0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Assembler::prefixq(Address adr) {}
|
||||
|
||||
inline void Assembler::prefix(Address adr, Register reg, bool byteinst) {}
|
||||
inline void Assembler::prefixq(Address adr, Register reg) {}
|
||||
inline void Assembler::prefix(Address adr, Register reg, bool byteinst, bool is_map1) {
|
||||
if (is_map1) {
|
||||
emit_int8(0x0F);
|
||||
}
|
||||
}
|
||||
inline void Assembler::prefixq(Address adr, Register reg, bool is_map1) {
|
||||
if (is_map1) {
|
||||
emit_int8(0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Assembler::prefix(Address adr, XMMRegister reg) {}
|
||||
inline void Assembler::prefixq(Address adr, XMMRegister reg) {}
|
||||
|
||||
#endif // _LP64
|
||||
|
||||
#endif // CPU_X86_ASSEMBLER_X86_INLINE_HPP
|
||||
|
@ -232,8 +232,10 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
|
||||
\
|
||||
product(bool, IntelJccErratumMitigation, true, DIAGNOSTIC, \
|
||||
"Turn off JVM mitigations related to Intel micro code " \
|
||||
"mitigations for the Intel JCC erratum")
|
||||
|
||||
"mitigations for the Intel JCC erratum") \
|
||||
\
|
||||
product(bool, UseAPX, false, EXPERIMENTAL, \
|
||||
"Use Advanced Performance Extensions on x86") \
|
||||
// end of ARCH_FLAGS
|
||||
|
||||
#endif // CPU_X86_GLOBALS_X86_HPP
|
||||
|
@ -1002,6 +1002,14 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
}
|
||||
|
||||
// APX support not enabled yet
|
||||
if (UseAPX) {
|
||||
if (!FLAG_IS_DEFAULT(UseAPX)) {
|
||||
warning("APX is not supported on this CPU.");
|
||||
}
|
||||
FLAG_SET_DEFAULT(UseAPX, false);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(IntelJccErratumMitigation)) {
|
||||
_has_intel_jcc_erratum = compute_has_intel_jcc_erratum();
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user