src/cpu/x86/vm/x86_64.ad
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/cpu/x86/vm/x86_64.ad Fri May 29 13:57:35 2015
--- new/src/cpu/x86/vm/x86_64.ad Fri May 29 13:57:35 2015
*** 164,175 ****
--- 164,178 ----
// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
//
// Class for all pointer registers (including RSP)
! reg_class any_reg(RAX, RAX_H,
+ // Empty register class.
! reg_class no_reg();
+
+ // Class for all pointer registers (including RSP and RBP)
+ reg_class any_reg_with_rbp(RAX, RAX_H,
RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
*** 182,193 ****
--- 185,218 ----
R12, R12_H,
R13, R13_H,
R14, R14_H,
R15, R15_H);
! // Class for all pointer registers except RSP
! reg_class ptr_reg(RAX, RAX_H,
! // Class for all pointer registers (including RSP, but excluding RBP)
! reg_class any_reg_no_rbp(RAX, RAX_H,
+ RDX, RDX_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);
+
+ // 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 %});
+
+ // Class for all pointer registers (excluding RSP)
+ reg_class ptr_reg_with_rbp(RAX, RAX_H,
RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
*** 197,208 ****
--- 222,250 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
! // Class for all pointer registers except RAX and RSP
! reg_class ptr_no_rax_reg(RDX, RDX_H,
! // Class for all pointer registers (excluding RSP and RBP)
! reg_class ptr_reg_no_rbp(RAX, RAX_H,
+ RDX, RDX_H,
+ RDI, RDI_H,
+ RSI, RSI_H,
+ RCX, RCX_H,
+ RBX, RBX_H,
+ R8, R8_H,
+ R9, R9_H,
+ R10, R10_H,
+ R11, R11_H,
+ 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 %});
+
+ // Class for all pointer registers (excluding RAX and RSP)
+ reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
RBX, RBX_H,
*** 211,222 ****
--- 253,264 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
reg_class ptr_no_rbp_reg(RDX, RDX_H,
! RAX, RAX_H,
+ // Class for all pointer registers (excluding RAX, RSP, and RBP)
! reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
RBX, RBX_H,
R8, R8_H,
*** 224,235 ****
--- 266,280 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
// Class for all pointer registers except RAX, RBX and RSP
! reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
+ // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp.
! reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %});
+
+ // Class for all pointer registers (excluding RAX, RBX, and RSP)
+ reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
R8, R8_H,
*** 237,246 ****
--- 282,306 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
+ // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP)
+ reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H,
+ RDI, RDI_H,
+ RSI, RSI_H,
+ RCX, RCX_H,
+ R8, R8_H,
+ R9, R9_H,
+ R10, R10_H,
+ R11, R11_H,
+ R13, R13_H,
+ R14, R14_H);
+
+ // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp.
+ reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %});
+
// Singleton class for RAX pointer register
reg_class ptr_rax_reg(RAX, RAX_H);
// Singleton class for RBX pointer register
reg_class ptr_rbx_reg(RBX, RBX_H);
*** 249,269 ****
--- 309,326 ----
reg_class ptr_rsi_reg(RSI, RSI_H);
// Singleton class for RDI pointer register
reg_class ptr_rdi_reg(RDI, RDI_H);
// Singleton class for RBP pointer register
reg_class ptr_rbp_reg(RBP, RBP_H);
// Singleton class for stack pointer
reg_class ptr_rsp_reg(RSP, RSP_H);
// Singleton class for TLS pointer
reg_class ptr_r15_reg(R15, R15_H);
! // Class for all long registers (except RSP)
! reg_class long_reg(RAX, RAX_H,
! // Class for all long registers (excluding RSP)
! reg_class long_reg_with_rbp(RAX, RAX_H,
RDX, RDX_H,
RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
*** 273,284 ****
--- 330,358 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
! // Class for all long registers except RAX, RDX (and RSP)
! reg_class long_no_rax_rdx_reg(RBP, RBP_H,
! // Class for all long registers (excluding RSP and RBP)
! reg_class long_reg_no_rbp(RAX, RAX_H,
+ RDX, RDX_H,
+ RDI, RDI_H,
+ RSI, RSI_H,
+ RCX, RCX_H,
+ RBX, RBX_H,
+ R8, R8_H,
+ R9, R9_H,
+ R10, R10_H,
+ R11, R11_H,
+ R13, R13_H,
+ R14, R14_H);
+
+ // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp.
+ reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %});
+
+ // Class for all long registers (excluding RAX, RDX and RSP)
+ reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RCX, RCX_H,
RBX, RBX_H,
R8, R8_H,
*** 286,297 ****
--- 360,386 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
! // Class for all long registers except RCX (and RSP)
! reg_class long_no_rcx_reg(RBP, RBP_H,
! // Class for all long registers (excluding RAX, RDX, RSP, and RBP)
! reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H,
+ RSI, RSI_H,
+ RCX, RCX_H,
+ RBX, RBX_H,
+ R8, R8_H,
+ R9, R9_H,
+ R10, R10_H,
+ R11, R11_H,
+ R13, R13_H,
+ R14, R14_H);
+
+ // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp.
+ reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %});
+
+ // Class for all long registers (excluding RCX and RSP)
+ reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H,
RDI, RDI_H,
RSI, RSI_H,
RAX, RAX_H,
RDX, RDX_H,
RBX, RBX_H,
*** 300,334 ****
--- 389,425 ----
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
! // Class for all long registers except RAX (and RSP)
! reg_class long_no_rax_reg(RBP, RBP_H,
RDX, RDX_H,
RDI, RDI_H,
! // Class for all long registers (excluding RCX, RSP, and RBP)
! reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H,
RSI, RSI_H,
! RCX, RCX_H,
! RAX, RAX_H,
+ RDX, RDX_H,
RBX, RBX_H,
R8, R8_H,
R9, R9_H,
R10, R10_H,
R11, R11_H,
R13, R13_H,
R14, R14_H);
+ // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp.
+ reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %});
+
// Singleton class for RAX long register
reg_class long_rax_reg(RAX, RAX_H);
// Singleton class for RCX long register
reg_class long_rcx_reg(RCX, RCX_H);
// Singleton class for RDX long register
reg_class long_rdx_reg(RDX, RDX_H);
! // Class for all int registers (except RSP)
! reg_class int_reg(RAX,
! // Class for all int registers (excluding RSP)
! reg_class int_reg_with_rbp(RAX,
RDX,
RBP,
RDI,
RSI,
RCX,
*** 338,349 ****
--- 429,457 ----
R10,
R11,
R13,
R14);
! // Class for all int registers except RCX (and RSP)
! reg_class int_no_rcx_reg(RAX,
! // Class for all int registers (excluding RSP and RBP)
! reg_class int_reg_no_rbp(RAX,
+ RDX,
+ RDI,
+ RSI,
+ RCX,
+ RBX,
+ R8,
+ R9,
+ R10,
+ R11,
+ R13,
+ R14);
+
+ // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp.
+ reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %});
+
+ // Class for all int registers (excluding RCX and RSP)
+ reg_class int_no_rcx_reg_with_rbp(RAX,
RDX,
RBP,
RDI,
RSI,
RBX,
*** 352,363 ****
--- 460,487 ----
R10,
R11,
R13,
R14);
! // Class for all int registers except RAX, RDX (and RSP)
! reg_class int_no_rax_rdx_reg(RBP,
! // Class for all int registers (excluding RCX, RSP, and RBP)
! reg_class int_no_rcx_reg_no_rbp(RAX,
+ RDX,
+ RDI,
+ RSI,
+ RBX,
+ R8,
+ R9,
+ R10,
+ R11,
+ R13,
+ R14);
+
+ // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp.
+ reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %});
+
+ // Class for all int registers (excluding RAX, RDX, and RSP)
+ reg_class int_no_rax_rdx_reg_with_rbp(RBP,
RDI,
RSI,
RCX,
RBX,
R8,
*** 365,374 ****
--- 489,513 ----
R10,
R11,
R13,
R14);
+ // Class for all int registers (excluding RAX, RDX, RSP, and RBP)
+ reg_class int_no_rax_rdx_reg_no_rbp(RDI,
+ RSI,
+ RCX,
+ RBX,
+ R8,
+ R9,
+ R10,
+ R11,
+ R13,
+ R14);
+
+ // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp.
+ reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %});
+
// Singleton class for RAX int register
reg_class int_rax_reg(RAX);
// Singleton class for RBX int register
reg_class int_rbx_reg(RBX);
*** 394,406 ****
--- 533,542 ----
#define RELOC_IMM64 Assembler::imm_operand
#define RELOC_DISP32 Assembler::disp32_operand
#define __ _masm.
static int preserve_SP_size() {
return 3; // rex.w, op, rm(reg/reg)
}
static int clear_avx_size() {
return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
}
// !!!!! Special hack to get all types of calls to specify the byte offset
*** 408,419 ****
--- 544,553 ----
// will point.
int MachCallStaticJavaNode::ret_addr_offset()
{
int offset = 5; // 5 bytes from start of call to where return address points
offset += clear_avx_size();
if (_method_handle_invoke)
offset += preserve_SP_size();
return offset;
}
int MachCallDynamicJavaNode::ret_addr_offset()
{
*** 448,467 ****
--- 582,591 ----
return round_to(current_offset, alignment_required()) - current_offset;
}
// The address of the call instruction needs to be 4-byte aligned to
// ensure that it does not span a cache line so that it can be patched.
int CallStaticJavaHandleNode::compute_padding(int current_offset) const
{
current_offset += preserve_SP_size(); // skip mov rbp, rsp
current_offset += clear_avx_size(); // skip vzeroupper
current_offset += 1; // skip call opcode byte
return round_to(current_offset, alignment_required()) - current_offset;
}
// The address of the call instruction needs to be 4-byte aligned to
// ensure that it does not span a cache line so that it can be patched.
int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
{
current_offset += clear_avx_size(); // skip vzeroupper
current_offset += 11; // skip movq instruction + call opcode byte
return round_to(current_offset, alignment_required()) - current_offset;
*** 722,740 ****
--- 846,872 ----
if (C->need_stack_bang(bangsize)) {
framesize -= wordSize;
st->print("# stack bang (%d bytes)", bangsize);
st->print("\n\t");
st->print("pushq rbp\t# Save rbp");
+ if (PreserveFramePointer) {
+ st->print("\n\t");
+ st->print("movq rbp, rsp\t# Save the caller's SP into rbp");
+ }
if (framesize) {
st->print("\n\t");
st->print("subq rsp, #%d\t# Create frame",framesize);
}
} else {
st->print("subq rsp, #%d\t# Create frame",framesize);
st->print("\n\t");
framesize -= wordSize;
st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
+ if (PreserveFramePointer) {
+ st->print("\n\t");
+ st->print("movq rbp, [rsp + #%d]\t# Save the caller's SP into rbp", (framesize + wordSize));
+ }
}
if (VerifyStackAtCalls) {
st->print("\n\t");
framesize -= wordSize;
*** 1596,1607 ****
--- 1728,1740 ----
// Register for MODL projection of divmodL
RegMask Matcher::modL_proj_mask() {
return LONG_RDX_REG_mask();
}
+ // Register for saving SP into on method handle invokes. Not used on x86_64.
const RegMask Matcher::method_handle_invoke_SP_save_mask() {
! return PTR_RBP_REG_mask();
! return NO_REG_mask();
}
%}
//----------ENCODING BLOCK-----------------------------------------------------
*** 3222,3233 ****
--- 3355,3366 ----
match(RegP);
match(rax_RegP);
match(rbx_RegP);
match(rdi_RegP);
match(rsi_RegP);
! match(rbp_RegP); // See Q&A below about
! match(r15_RegP); // See Q&A below about r15_RegP.
! match(r15_RegP); // r15_RegP and rbp_RegP.
format %{ %}
interface(REG_INTER);
%}
*** 3239,3253 ****
--- 3372,3389 ----
interface(REG_INTER);
%}
// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
// Answer: Operand match rules govern the DFA as it processes instruction inputs.
! // It's fine for an instruction input which expects rRegP to match a r15_RegP.
! // It's fine for an instruction input that expects rRegP to match a r15_RegP.
// The output of an instruction is controlled by the allocator, which respects
// register class masks, not match rules. Unless an instruction mentions
// r15_RegP or any_RegP explicitly as its output, r15 will not be considered
// by the allocator as an input.
+ // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true,
+ // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a
+ // result, RBP is not included in the output of the instruction either.
operand no_rax_RegP()
%{
constraint(ALLOC_IN_RC(ptr_no_rax_reg));
match(RegP);
*** 3257,3269 ****
--- 3393,3407 ----
format %{ %}
interface(REG_INTER);
%}
+ // This operand is not allowed to use RBP even if
+ // RBP is not used to hold the frame pointer.
operand no_rbp_RegP()
%{
! constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
! constraint(ALLOC_IN_RC(ptr_reg_no_rbp));
match(RegP);
match(rbx_RegP);
match(rsi_RegP);
match(rdi_RegP);
*** 3336,3355 ****
--- 3474,3483 ----
format %{ %}
interface(REG_INTER);
%}
operand rbp_RegP()
%{
constraint(ALLOC_IN_RC(ptr_rbp_reg));
match(RegP);
match(rRegP);
format %{ %}
interface(REG_INTER);
%}
operand r15_RegP()
%{
constraint(ALLOC_IN_RC(ptr_r15_reg));
match(RegP);
match(rRegP);
*** 11412,11453 ****
--- 11540,11559 ----
// Call Java Static Instruction
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
instruct CallStaticJavaDirect(method meth) %{
match(CallStaticJava);
predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
effect(USE meth);
ins_cost(300);
format %{ "call,static " %}
opcode(0xE8); /* E8 cd */
ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
ins_pipe(pipe_slow);
ins_alignment(4);
%}
// Call Java Static Instruction (method handle version)
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
match(CallStaticJava);
predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
effect(USE meth);
// RBP is saved by all callees (for interpreter stack correction).
// We use it here for a similar purpose, in {preserve,restore}_SP.
ins_cost(300);
format %{ "call,static/MethodHandle " %}
opcode(0xE8); /* E8 cd */
ins_encode(clear_avx, preserve_SP,
Java_Static_Call(meth),
restore_SP,
call_epilog);
ins_pipe(pipe_slow);
ins_alignment(4);
%}
// Call Java Dynamic Instruction
// Note: If this code changes, the corresponding ret_addr_offset() and
// compute_padding() functions will have to be adjusted.
instruct CallDynamicJavaDirect(method meth)
%{
src/cpu/x86/vm/x86_64.ad
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File