# HG changeset patch # User dlong # Date 1550125772 28800 # Wed Feb 13 22:29:32 2019 -0800 # Node ID 6889b5e36cbe9508ce0f3896e8723f8edb3134f3 # Parent b9addb1cfe9c749b1135d85fab21bc0e95c41635 [mq]: ad2 diff --git a/src/hotspot/cpu/x86/c2_init_x86.cpp b/src/hotspot/cpu/x86/c2_init_x86.cpp --- a/src/hotspot/cpu/x86/c2_init_x86.cpp +++ b/src/hotspot/cpu/x86/c2_init_x86.cpp @@ -29,6 +29,8 @@ // processor dependent initialization for i486 +extern void reg_mask_init(); + void Compile::pd_compiler2_init() { guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" ); // QQQ presumably all 64bit cpu's support this. Seems like the ifdef could @@ -58,4 +60,5 @@ OptoReg::invalidate(i); } } + reg_mask_init(); } diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -169,6 +169,24 @@ // Empty register class. reg_class no_reg(); +// Class for all pointer registers +reg_class all_reg(RAX, RAX_H, + RDX, RDX_H, + RBP, RBP_H, + RDI, RDI_H, + RSI, RSI_H, + RCX, RCX_H, + RBX, RBX_H, + RSP, RSP_H, + R8, R8_H, + R9, R9_H, + R10, R10_H, + R11, R11_H, + R12, R12_H, + R13, R13_H, + R14, R14_H, + R15, R15_H); + // Class for all pointer registers (including RSP and RBP) reg_class any_reg_with_rbp(RAX, RAX_H, RDX, RDX_H, @@ -207,7 +225,7 @@ // Dynamic register class that selects at runtime between register classes // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; -reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); +reg_class_dynamic any_reg0(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); // Class for all pointer registers (excluding RSP) reg_class ptr_reg_with_rbp(RAX, RAX_H, @@ -225,7 +243,7 @@ R14, R14_H); // Class for all pointer registers (excluding RSP and RBP) -reg_class ptr_reg_no_rbp(RAX, RAX_H, +reg_class ptr_reg_no_rbp0(RAX, RAX_H, RDX, RDX_H, RDI, RDI_H, RSI, RSI_H, @@ -238,8 +256,23 @@ R13, R13_H, R14, R14_H); -// Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. -reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); +// Dynamic register class that selects between ptr_reg_no_rbp0 and ptr_reg_with_rbp. +reg_class_dynamic ptr_reg0(ptr_reg_no_rbp0, ptr_reg_with_rbp, %{ PreserveFramePointer %}); + +// Class for all pointer registers +reg_class any_reg %{ + return _ANY_REG_mask; +%} + +// Class for all pointer registers (excluding RSP) +reg_class ptr_reg %{ + return _PTR_REG_mask; +%} + +// Class for all pointer registers (excluding RSP and RBP) +reg_class ptr_reg_no_rbp %{ + return _PTR_REG_NO_RBP_mask; +%} // Class for all pointer registers (excluding RAX and RSP) reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, @@ -529,12 +562,61 @@ //----------SOURCE BLOCK------------------------------------------------------- // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description +source_hpp %{ +extern RegMask _ANY_REG_mask; +extern RegMask _PTR_REG_mask; +extern RegMask _PTR_REG_NO_RBP_mask; +extern RegMask _STACK_OR_PTR_REG_mask; +inline const RegMask &STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } +%} + source %{ #define RELOC_IMM64 Assembler::imm_operand #define RELOC_DISP32 Assembler::disp32_operand #define __ _masm. +RegMask _ANY_REG_mask; +RegMask _PTR_REG_mask; +RegMask _PTR_REG_NO_RBP_mask; +RegMask _STACK_OR_PTR_REG_mask; + +#ifdef ASSERT +static bool same_mask(const RegMask &a, const RegMask &b) { + RegMask a_sub_b = a; a_sub_b.SUBTRACT(b); + RegMask b_sub_a = b; b_sub_a.SUBTRACT(a); + return a_sub_b.Size() == 0 && b_sub_a.Size() == 0; +} +#endif + +void reg_mask_init() { + // _ALL_REG_mask is generated by adlc from the all_reg register class below. + // We derive a number of subsets from it. + _ANY_REG_mask = _ALL_REG_mask; + if (PreserveFramePointer) { + _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); + _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); + } + + _PTR_REG_mask = _ANY_REG_mask; + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15_thread->as_VMReg())); + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15_thread->as_VMReg()->next())); + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); + if (UseCompressedOops || UseCompressedClassPointers || UseZGC) { + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r12_heapbase->as_VMReg())); + _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r12_heapbase->as_VMReg()->next())); + } + _PTR_REG_NO_RBP_mask = _PTR_REG_mask; + _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); + _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); + _STACK_OR_PTR_REG_mask = _PTR_REG_mask; + _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); + assert(same_mask(_ANY_REG_mask, ANY_REG0_mask()), "!"); + assert(same_mask(_PTR_REG_mask, PTR_REG0_mask()), "!"); + assert(same_mask(_PTR_REG_NO_RBP_mask, PTR_REG_NO_RBP0_mask()), "!"); +} + static bool generate_vzeroupper(Compile* C) { return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper } diff --git a/src/hotspot/share/adlc/formsopt.hpp b/src/hotspot/share/adlc/formsopt.hpp --- a/src/hotspot/share/adlc/formsopt.hpp +++ b/src/hotspot/share/adlc/formsopt.hpp @@ -242,9 +242,6 @@ char* code_snippet() { return _code_snippet; } - void set_stack_version(bool flag) { - assert(false, "User defined register classes are not allowed to spill to the stack."); - } void declare_register_masks(FILE* fp); void build_register_masks(FILE* fp) { // We do not need to generate register masks because we select at runtime