--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Nov 09 13:27:18 2015 +0000
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Nov 09 11:26:41 2015 -0800
@@ -438,6 +438,8 @@
};
+class InstructionAttr;
+
// 64-bit refect the fxsave size which is 512 bytes and the new xsave area on EVEX which is another 2176 bytes
// See fxsave and xsave(EVEX enabled) documentation for layout
const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY(2688 / wordSize);
@@ -568,7 +570,8 @@
EVEX_8bit = 0,
EVEX_16bit = 1,
EVEX_32bit = 2,
- EVEX_64bit = 3
+ EVEX_64bit = 3,
+ EVEX_NObit = 4
};
enum WhichOperand {
@@ -598,16 +601,12 @@
private:
- int _evex_encoding;
- int _input_size_in_bits;
- int _avx_vector_len;
- int _tuple_type;
- bool _is_evex_instruction;
bool _legacy_mode_bw;
bool _legacy_mode_dq;
bool _legacy_mode_vl;
bool _legacy_mode_vlbw;
- bool _instruction_uses_vl;
+
+ class InstructionAttr *_attributes;
// 64bit prefixes
int prefix_and_encode(int reg_enc, bool byteinst = false);
@@ -637,181 +636,30 @@
int rex_prefix_and_encode(int dst_enc, int src_enc,
VexSimdPrefix pre, VexOpcode opc, bool rex_w);
- void vex_prefix(bool vex_r, bool vex_b, bool vex_x, bool vex_w,
- int nds_enc, VexSimdPrefix pre, VexOpcode opc,
- int vector_len);
+ 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 vex_w, bool evex_r, bool evex_v,
- int nds_enc, VexSimdPrefix pre, VexOpcode opc,
- bool is_extended_context, bool is_merge_context,
- int vector_len, bool no_mask_reg );
+ 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 vex_prefix(Address adr, int nds_enc, int xreg_enc,
VexSimdPrefix pre, VexOpcode opc,
- bool vex_w, int vector_len,
- bool legacy_mode = false, bool no_mask_reg = false);
-
- void vex_prefix(XMMRegister dst, XMMRegister nds, Address src,
- VexSimdPrefix pre, int vector_len = AVX_128bit,
- bool no_mask_reg = false, bool legacy_mode = false) {
- int dst_enc = dst->encoding();
- int nds_enc = nds->is_valid() ? nds->encoding() : 0;
- vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, false, vector_len, legacy_mode, no_mask_reg);
- }
-
- void vex_prefix_q(XMMRegister dst, XMMRegister nds, Address src,
- VexSimdPrefix pre, int vector_len = AVX_128bit,
- bool no_mask_reg = false) {
- int dst_enc = dst->encoding();
- int nds_enc = nds->is_valid() ? nds->encoding() : 0;
- vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, true, vector_len, false, no_mask_reg);
- }
-
- void vex_prefix_0F38(Register dst, Register nds, Address src, bool no_mask_reg = false) {
- bool vex_w = false;
- int vector_len = AVX_128bit;
- vex_prefix(src, nds->encoding(), dst->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
- vector_len, no_mask_reg);
- }
-
- void vex_prefix_0F38_legacy(Register dst, Register nds, Address src, bool no_mask_reg = false) {
- bool vex_w = false;
- int vector_len = AVX_128bit;
- vex_prefix(src, nds->encoding(), dst->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
- vector_len, true, no_mask_reg);
- }
-
- void vex_prefix_0F38_q(Register dst, Register nds, Address src, bool no_mask_reg = false) {
- bool vex_w = true;
- int vector_len = AVX_128bit;
- vex_prefix(src, nds->encoding(), dst->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
- vector_len, no_mask_reg);
- }
-
- void vex_prefix_0F38_q_legacy(Register dst, Register nds, Address src, bool no_mask_reg = false) {
- bool vex_w = true;
- int vector_len = AVX_128bit;
- vex_prefix(src, nds->encoding(), dst->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
- vector_len, true, no_mask_reg);
- }
+ InstructionAttr *attributes);
int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
VexSimdPrefix pre, VexOpcode opc,
- bool vex_w, int vector_len,
- bool legacy_mode, bool no_mask_reg);
-
- int vex_prefix_0F38_and_encode(Register dst, Register nds, Register src, bool no_mask_reg = false) {
- bool vex_w = false;
- int vector_len = AVX_128bit;
- return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
- false, no_mask_reg);
- }
-
- int vex_prefix_0F38_and_encode_legacy(Register dst, Register nds, Register src, bool no_mask_reg = false) {
- bool vex_w = false;
- int vector_len = AVX_128bit;
- return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
- true, no_mask_reg);
- }
-
- int vex_prefix_0F38_and_encode_q(Register dst, Register nds, Register src, bool no_mask_reg = false) {
- bool vex_w = true;
- int vector_len = AVX_128bit;
- return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
- false, no_mask_reg);
- }
+ InstructionAttr *attributes);
- int vex_prefix_0F38_and_encode_q_legacy(Register dst, Register nds, Register src, bool no_mask_reg = false) {
- bool vex_w = true;
- int vector_len = AVX_128bit;
- return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
- VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
- true, no_mask_reg);
- }
-
- int vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
- VexSimdPrefix pre, int vector_len = AVX_128bit,
- VexOpcode opc = VEX_OPCODE_0F, bool legacy_mode = false,
- bool no_mask_reg = false) {
- int src_enc = src->encoding();
- int dst_enc = dst->encoding();
- int nds_enc = nds->is_valid() ? nds->encoding() : 0;
- return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, false, vector_len, legacy_mode, no_mask_reg);
- }
-
- void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr,
- VexSimdPrefix pre, bool no_mask_reg, VexOpcode opc = VEX_OPCODE_0F,
- bool rex_w = false, int vector_len = AVX_128bit, bool legacy_mode = false);
-
- void simd_prefix(XMMRegister dst, Address src, VexSimdPrefix pre,
- bool no_mask_reg, VexOpcode opc = VEX_OPCODE_0F) {
- simd_prefix(dst, xnoreg, src, pre, no_mask_reg, opc);
- }
+ void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr, VexSimdPrefix pre,
+ VexOpcode opc, InstructionAttr *attributes);
- void simd_prefix(Address dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg) {
- simd_prefix(src, dst, pre, no_mask_reg);
- }
- void simd_prefix_q(XMMRegister dst, XMMRegister nds, Address src,
- VexSimdPrefix pre, bool no_mask_reg = false) {
- bool rex_w = true;
- simd_prefix(dst, nds, src, pre, no_mask_reg, VEX_OPCODE_0F, rex_w);
- }
-
- int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
- VexSimdPrefix pre, bool no_mask_reg,
- VexOpcode opc = VEX_OPCODE_0F,
- bool rex_w = false, int vector_len = AVX_128bit,
- bool legacy_mode = false);
-
- int kreg_prefix_and_encode(KRegister dst, KRegister nds, KRegister src,
- VexSimdPrefix pre, bool no_mask_reg,
- VexOpcode opc = VEX_OPCODE_0F,
- bool rex_w = false, int vector_len = AVX_128bit);
-
- int kreg_prefix_and_encode(KRegister dst, KRegister nds, Register src,
- VexSimdPrefix pre, bool no_mask_reg,
- VexOpcode opc = VEX_OPCODE_0F,
- bool rex_w = false, int vector_len = AVX_128bit);
+ int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src, VexSimdPrefix pre,
+ VexOpcode opc, InstructionAttr *attributes);
- // Move/convert 32-bit integer value.
- int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, Register src,
- VexSimdPrefix pre, bool no_mask_reg) {
- // It is OK to cast from Register to XMMRegister to pass argument here
- // since only encoding is used in simd_prefix_and_encode() and number of
- // Gen and Xmm registers are the same.
- return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre, no_mask_reg, VEX_OPCODE_0F);
- }
- int simd_prefix_and_encode(XMMRegister dst, Register src, VexSimdPrefix pre, bool no_mask_reg) {
- return simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg);
- }
- int simd_prefix_and_encode(Register dst, XMMRegister src,
- VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
- bool no_mask_reg = false) {
- return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, no_mask_reg, opc);
- }
+ int kreg_prefix_and_encode(KRegister dst, KRegister nds, KRegister src, VexSimdPrefix pre,
+ VexOpcode opc, InstructionAttr *attributes);
- // Move/convert 64-bit integer value.
- int simd_prefix_and_encode_q(XMMRegister dst, XMMRegister nds, Register src,
- VexSimdPrefix pre, bool no_mask_reg = false) {
- bool rex_w = true;
- return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre, no_mask_reg, VEX_OPCODE_0F, rex_w);
- }
- int simd_prefix_and_encode_q(XMMRegister dst, Register src, VexSimdPrefix pre, bool no_mask_reg) {
- return simd_prefix_and_encode_q(dst, xnoreg, src, pre, no_mask_reg);
- }
- int simd_prefix_and_encode_q(Register dst, XMMRegister src,
- VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
- bool no_mask_reg = false) {
- bool rex_w = true;
- return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, no_mask_reg, opc, rex_w);
- }
+ int kreg_prefix_and_encode(KRegister dst, KRegister nds, Register src, VexSimdPrefix pre,
+ VexOpcode opc, InstructionAttr *attributes);
// Helper functions for groups of instructions
void emit_arith_b(int op1, int op2, Register dst, int imm8);
@@ -821,27 +669,6 @@
void emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32);
void emit_arith(int op1, int op2, Register dst, Register src);
- void emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
- void emit_simd_arith_q(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
- void emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
- void emit_simd_arith_q(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false);
- void emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
- void emit_simd_arith_nonds_q(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
- void emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
- void emit_simd_arith_nonds_q(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false);
- void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
- Address src, VexSimdPrefix pre, int vector_len,
- bool no_mask_reg = false, bool legacy_mode = false);
- void emit_vex_arith_q(int opcode, XMMRegister dst, XMMRegister nds,
- Address src, VexSimdPrefix pre, int vector_len,
- bool no_mask_reg = false);
- void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
- XMMRegister src, VexSimdPrefix pre, int vector_len,
- bool no_mask_reg = false, bool legacy_mode = false);
- void emit_vex_arith_q(int opcode, XMMRegister dst, XMMRegister nds,
- XMMRegister src, VexSimdPrefix pre, int vector_len,
- bool no_mask_reg = false);
-
bool emit_compressed_disp_byte(int &disp);
void emit_operand(Register reg,
@@ -986,18 +813,16 @@
// belong in macro assembler but there is no need for both varieties to exist
void init_attributes(void) {
- _evex_encoding = 0;
- _input_size_in_bits = 0;
- _avx_vector_len = AVX_NoVec;
- _tuple_type = EVEX_ETUP;
- _is_evex_instruction = false;
_legacy_mode_bw = (VM_Version::supports_avx512bw() == false);
_legacy_mode_dq = (VM_Version::supports_avx512dq() == false);
_legacy_mode_vl = (VM_Version::supports_avx512vl() == false);
_legacy_mode_vlbw = (VM_Version::supports_avx512vlbw() == false);
- _instruction_uses_vl = false;
+ _attributes = NULL;
}
+ void set_attributes(InstructionAttr *attributes) { _attributes = attributes; }
+ void clear_attributes(void) { _attributes = NULL; }
+
void lea(Register dst, Address src);
void mov(Register dst, Register src);
@@ -2106,12 +1931,12 @@
void vextracti128h(Address dst, XMMRegister src);
// Copy low 256bit into high 256bit of ZMM registers.
- void vinserti64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src);
- void vinsertf64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src);
- void vextracti64x4h(XMMRegister dst, XMMRegister src);
- void vextractf64x4h(XMMRegister dst, XMMRegister src);
- void vextractf64x4h(Address dst, XMMRegister src);
- void vinsertf64x4h(XMMRegister dst, Address src);
+ void vinserti64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src, int value);
+ void vinsertf64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src, int value);
+ void vextracti64x4h(XMMRegister dst, XMMRegister src, int value);
+ void vextractf64x4h(XMMRegister dst, XMMRegister src, int value);
+ void vextractf64x4h(Address dst, XMMRegister src, int value);
+ void vinsertf64x4h(XMMRegister dst, Address src, int value);
// Copy targeted 128bit segments of the ZMM registers
void vextracti64x2h(XMMRegister dst, XMMRegister src, int value);
@@ -2173,4 +1998,95 @@
};
+// The Intel x86/Amd64 Assembler attributes: All fields enclosed here are to guide encoding level decisions.
+// Specific set functions are for specialized use, else defaults or whatever was supplied to object construction
+// are applied.
+class InstructionAttr {
+public:
+ InstructionAttr(
+ int vector_len,
+ bool rex_vex_w,
+ bool legacy_mode,
+ bool no_reg_mask,
+ bool uses_vl)
+ :
+ _avx_vector_len(vector_len),
+ _rex_vex_w(rex_vex_w),
+ _legacy_mode(legacy_mode),
+ _no_reg_mask(no_reg_mask),
+ _uses_vl(uses_vl),
+ _tuple_type(Assembler::EVEX_ETUP),
+ _input_size_in_bits(Assembler::EVEX_NObit),
+ _is_evex_instruction(false),
+ _evex_encoding(0),
+ _is_clear_context(false),
+ _is_extended_context(false),
+ _current_assembler(NULL) {
+ if (UseAVX < 3) _legacy_mode = true;
+ }
+
+ ~InstructionAttr() {
+ if (_current_assembler != NULL) {
+ _current_assembler->clear_attributes();
+ }
+ _current_assembler = NULL;
+ }
+
+private:
+ int _avx_vector_len;
+ bool _rex_vex_w;
+ bool _legacy_mode;
+ bool _no_reg_mask;
+ bool _uses_vl;
+ int _tuple_type;
+ int _input_size_in_bits;
+ bool _is_evex_instruction;
+ int _evex_encoding;
+ bool _is_clear_context;
+ bool _is_extended_context;
+
+ Assembler *_current_assembler;
+
+public:
+ // query functions for field accessors
+ int get_vector_len(void) const { return _avx_vector_len; }
+ bool is_rex_vex_w(void) const { return _rex_vex_w; }
+ bool is_legacy_mode(void) const { return _legacy_mode; }
+ bool is_no_reg_mask(void) const { return _no_reg_mask; }
+ bool uses_vl(void) const { return _uses_vl; }
+ int get_tuple_type(void) const { return _tuple_type; }
+ int get_input_size(void) const { return _input_size_in_bits; }
+ int is_evex_instruction(void) const { return _is_evex_instruction; }
+ int get_evex_encoding(void) const { return _evex_encoding; }
+ bool is_clear_context(void) const { return _is_clear_context; }
+ bool is_extended_context(void) const { return _is_extended_context; }
+
+ // Set the vector len manually
+ void set_vector_len(int vector_len) { _avx_vector_len = vector_len; }
+
+ // Set the instruction to be encoded in AVX mode
+ void set_is_legacy_mode(void) { _legacy_mode = true; }
+
+ // Set the current instuction to be encoded as an EVEX instuction
+ void set_is_evex_instruction(void) { _is_evex_instruction = true; }
+
+ // Internal encoding data used in compressed immediate offset programming
+ void set_evex_encoding(int value) { _evex_encoding = value; }
+
+ // Set the Evex.Z field to be used to clear all non directed XMM/YMM/ZMM components
+ void set_is_clear_context(void) { _is_clear_context = true; }
+
+ // Map back to current asembler so that we can manage object level assocation
+ void set_current_assembler(Assembler *current_assembler) { _current_assembler = current_assembler; }
+
+ // Address modifiers used for compressed displacement calculation
+ void set_address_attributes(int tuple_type, int input_size_in_bits) {
+ if (VM_Version::supports_evex()) {
+ _tuple_type = tuple_type;
+ _input_size_in_bits = input_size_in_bits;
+ }
+ }
+
+};
+
#endif // CPU_X86_VM_ASSEMBLER_X86_HPP