< prev index next >

src/cpu/x86/vm/x86_64.ad

Print this page




 383 reg_class int_rdi_reg(RDI);
 384 
 385 // Singleton class for instruction pointer
 386 // reg_class ip_reg(RIP);
 387 
 388 %}
 389 
 390 //----------SOURCE BLOCK-------------------------------------------------------
 391 // This is a block of C++ code which provides values, functions, and
 392 // definitions necessary in the rest of the architecture description
 393 source %{
 394 #define   RELOC_IMM64    Assembler::imm_operand
 395 #define   RELOC_DISP32   Assembler::disp32_operand
 396 
 397 #define __ _masm.
 398 
 399 static int preserve_SP_size() {
 400   return 3;  // rex.w, op, rm(reg/reg)
 401 }
 402 static int clear_avx_size() {



 403   return (Compile::current()->max_vector_size() > 16) ? 3 : 0;  // vzeroupper

 404 }
 405 
 406 // !!!!! Special hack to get all types of calls to specify the byte offset
 407 //       from the start of the call to the point where the return address
 408 //       will point.
 409 int MachCallStaticJavaNode::ret_addr_offset()
 410 {
 411   int offset = 5; // 5 bytes from start of call to where return address points
 412   offset += clear_avx_size();
 413   if (_method_handle_invoke)
 414     offset += preserve_SP_size();
 415   return offset;
 416 }
 417 
 418 int MachCallDynamicJavaNode::ret_addr_offset()
 419 {
 420   int offset = 15; // 15 bytes from start of call to where return address points
 421   offset += clear_avx_size();
 422   return offset;
 423 }


 921       __ movq(Address(rsp, -8), rax);
 922       __ movl(rax, Address(rsp, src_offset));
 923       __ movl(Address(rsp, dst_offset), rax);
 924       __ movq(rax, Address(rsp, -8));
 925       break;
 926     case Op_VecD:
 927       __ pushq(Address(rsp, src_offset));
 928       __ popq (Address(rsp, dst_offset));
 929       break;
 930     case Op_VecX:
 931       __ pushq(Address(rsp, src_offset));
 932       __ popq (Address(rsp, dst_offset));
 933       __ pushq(Address(rsp, src_offset+8));
 934       __ popq (Address(rsp, dst_offset+8));
 935       break;
 936     case Op_VecY:
 937       __ vmovdqu(Address(rsp, -32), xmm0);
 938       __ vmovdqu(xmm0, Address(rsp, src_offset));
 939       __ vmovdqu(Address(rsp, dst_offset), xmm0);
 940       __ vmovdqu(xmm0, Address(rsp, -32));





 941       break;
 942     default:
 943       ShouldNotReachHere();
 944     }
 945 #ifndef PRODUCT
 946   } else {
 947     switch (ireg) {
 948     case Op_VecS:
 949       st->print("movq    [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
 950                 "movl    rax, [rsp + #%d]\n\t"
 951                 "movl    [rsp + #%d], rax\n\t"
 952                 "movq    rax, [rsp - #8]",
 953                 src_offset, dst_offset);
 954       break;
 955     case Op_VecD:
 956       st->print("pushq   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
 957                 "popq    [rsp + #%d]",
 958                 src_offset, dst_offset);
 959       break;
 960      case Op_VecX:
 961       st->print("pushq   [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
 962                 "popq    [rsp + #%d]\n\t"
 963                 "pushq   [rsp + #%d]\n\t"
 964                 "popq    [rsp + #%d]",
 965                 src_offset, dst_offset, src_offset+8, dst_offset+8);
 966       break;
 967     case Op_VecY:
 968       st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
 969                 "vmovdqu xmm0, [rsp + #%d]\n\t"
 970                 "vmovdqu [rsp + #%d], xmm0\n\t"
 971                 "vmovdqu xmm0, [rsp - #32]",
 972                 src_offset, dst_offset);
 973       break;







 974     default:
 975       ShouldNotReachHere();
 976     }
 977 #endif
 978   }
 979 }
 980 
 981 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
 982                                        PhaseRegAlloc* ra_,
 983                                        bool do_size,
 984                                        outputStream* st) const {
 985   assert(cbuf != NULL || st  != NULL, "sanity");
 986   // Get registers to move
 987   OptoReg::Name src_second = ra_->get_reg_second(in(1));
 988   OptoReg::Name src_first = ra_->get_reg_first(in(1));
 989   OptoReg::Name dst_second = ra_->get_reg_second(this);
 990   OptoReg::Name dst_first = ra_->get_reg_first(this);
 991 
 992   enum RC src_second_rc = rc_class(src_second);
 993   enum RC src_first_rc = rc_class(src_first);
 994   enum RC dst_second_rc = rc_class(dst_second);
 995   enum RC dst_first_rc = rc_class(dst_first);
 996 
 997   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
 998          "must move at least 1 register" );
 999 
1000   if (src_first == dst_first && src_second == dst_second) {
1001     // Self copy, no move
1002     return 0;
1003   }
1004   if (bottom_type()->isa_vect() != NULL) {
1005     uint ireg = ideal_reg();
1006     assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1007     assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
1008     if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1009       // mem -> mem
1010       int src_offset = ra_->reg2offset(src_first);
1011       int dst_offset = ra_->reg2offset(dst_first);
1012       vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1013     } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1014       vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
1015     } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1016       int stack_offset = ra_->reg2offset(dst_first);
1017       vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
1018     } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1019       int stack_offset = ra_->reg2offset(src_first);
1020       vec_spill_helper(cbuf, false, true,  stack_offset, dst_first, ireg, st);
1021     } else {
1022       ShouldNotReachHere();
1023     }
1024     return 0;
1025   }
1026   if (src_first_rc == rc_stack) {
1027     // mem ->


2682       0,
2683       0,
2684       RAX_num,  // Op_RegN
2685       RAX_num,  // Op_RegI
2686       RAX_num,  // Op_RegP
2687       XMM0_num, // Op_RegF
2688       XMM0_num, // Op_RegD
2689       RAX_num   // Op_RegL
2690     };
2691     static const int hi[Op_RegL + 1] = {
2692       0,
2693       0,
2694       OptoReg::Bad, // Op_RegN
2695       OptoReg::Bad, // Op_RegI
2696       RAX_H_num,    // Op_RegP
2697       OptoReg::Bad, // Op_RegF
2698       XMM0b_num,    // Op_RegD
2699       RAX_H_num     // Op_RegL
2700     };
2701     // Excluded flags and vector registers.
2702     assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
2703     return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2704   %}
2705 %}
2706 
2707 //----------ATTRIBUTES---------------------------------------------------------
2708 //----------Operand Attributes-------------------------------------------------
2709 op_attrib op_cost(0);        // Required cost attribute
2710 
2711 //----------Instruction Attributes---------------------------------------------
2712 ins_attrib ins_cost(100);       // Required cost attribute
2713 ins_attrib ins_size(8);         // Required size attribute (in bits)
2714 ins_attrib ins_short_branch(0); // Required flag: is this instruction
2715                                 // a non-matching short branch variant
2716                                 // of some long branch?
2717 ins_attrib ins_alignment(1);    // Required alignment attribute (must
2718                                 // be a power of 2) specifies the
2719                                 // alignment that some part of the
2720                                 // instruction (not necessarily the
2721                                 // start) requires.  If > 1, a
2722                                 // compute_padding() function must be


3443 
3444 // Flags register, used as output of FLOATING POINT compare instructions
3445 operand rFlagsRegU()
3446 %{
3447   constraint(ALLOC_IN_RC(int_flags));
3448   match(RegFlags);
3449 
3450   format %{ "RFLAGS_U" %}
3451   interface(REG_INTER);
3452 %}
3453 
3454 operand rFlagsRegUCF() %{
3455   constraint(ALLOC_IN_RC(int_flags));
3456   match(RegFlags);
3457   predicate(false);
3458 
3459   format %{ "RFLAGS_U_CF" %}
3460   interface(REG_INTER);
3461 %}
3462 
3463 // Float register operands
3464 operand regF()
3465 %{
3466   constraint(ALLOC_IN_RC(float_reg));
3467   match(RegF);
3468 
3469   format %{ %}
3470   interface(REG_INTER);
3471 %}
3472 
3473 // Double register operands
3474 operand regD()
3475 %{
3476   constraint(ALLOC_IN_RC(double_reg));
3477   match(RegD);
3478 
3479   format %{ %}
3480   interface(REG_INTER);
3481 %}
3482 

































3483 //----------Memory Operands----------------------------------------------------
3484 // Direct Memory Operand
3485 // operand direct(immP addr)
3486 // %{
3487 //   match(addr);
3488 
3489 //   format %{ "[$addr]" %}
3490 //   interface(MEMORY_INTER) %{
3491 //     base(0xFFFFFFFF);
3492 //     index(0x4);
3493 //     scale(0x0);
3494 //     disp($addr);
3495 //   %}
3496 // %}
3497 
3498 // Indirect Memory Operand
3499 operand indirect(any_RegP reg)
3500 %{
3501   constraint(ALLOC_IN_RC(ptr_reg));
3502   match(reg);




 383 reg_class int_rdi_reg(RDI);
 384 
 385 // Singleton class for instruction pointer
 386 // reg_class ip_reg(RIP);
 387 
 388 %}
 389 
 390 //----------SOURCE BLOCK-------------------------------------------------------
 391 // This is a block of C++ code which provides values, functions, and
 392 // definitions necessary in the rest of the architecture description
 393 source %{
 394 #define   RELOC_IMM64    Assembler::imm_operand
 395 #define   RELOC_DISP32   Assembler::disp32_operand
 396 
 397 #define __ _masm.
 398 
 399 static int preserve_SP_size() {
 400   return 3;  // rex.w, op, rm(reg/reg)
 401 }
 402 static int clear_avx_size() {
 403   if(UseAVX > 2) {
 404     return 0; // vzeroupper is ignored
 405   } else {
 406     return (Compile::current()->max_vector_size() > 16) ? 3 : 0;  // vzeroupper
 407   }
 408 }
 409 
 410 // !!!!! Special hack to get all types of calls to specify the byte offset
 411 //       from the start of the call to the point where the return address
 412 //       will point.
 413 int MachCallStaticJavaNode::ret_addr_offset()
 414 {
 415   int offset = 5; // 5 bytes from start of call to where return address points
 416   offset += clear_avx_size();
 417   if (_method_handle_invoke)
 418     offset += preserve_SP_size();
 419   return offset;
 420 }
 421 
 422 int MachCallDynamicJavaNode::ret_addr_offset()
 423 {
 424   int offset = 15; // 15 bytes from start of call to where return address points
 425   offset += clear_avx_size();
 426   return offset;
 427 }


 925       __ movq(Address(rsp, -8), rax);
 926       __ movl(rax, Address(rsp, src_offset));
 927       __ movl(Address(rsp, dst_offset), rax);
 928       __ movq(rax, Address(rsp, -8));
 929       break;
 930     case Op_VecD:
 931       __ pushq(Address(rsp, src_offset));
 932       __ popq (Address(rsp, dst_offset));
 933       break;
 934     case Op_VecX:
 935       __ pushq(Address(rsp, src_offset));
 936       __ popq (Address(rsp, dst_offset));
 937       __ pushq(Address(rsp, src_offset+8));
 938       __ popq (Address(rsp, dst_offset+8));
 939       break;
 940     case Op_VecY:
 941       __ vmovdqu(Address(rsp, -32), xmm0);
 942       __ vmovdqu(xmm0, Address(rsp, src_offset));
 943       __ vmovdqu(Address(rsp, dst_offset), xmm0);
 944       __ vmovdqu(xmm0, Address(rsp, -32));
 945     case Op_VecZ:
 946       __ evmovdqu(Address(rsp, -64), xmm0, 2);
 947       __ evmovdqu(xmm0, Address(rsp, src_offset), 2);
 948       __ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
 949       __ evmovdqu(xmm0, Address(rsp, -64), 2);
 950       break;
 951     default:
 952       ShouldNotReachHere();
 953     }
 954 #ifndef PRODUCT
 955   } else {
 956     switch (ireg) {
 957     case Op_VecS:
 958       st->print("movq    [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
 959                 "movl    rax, [rsp + #%d]\n\t"
 960                 "movl    [rsp + #%d], rax\n\t"
 961                 "movq    rax, [rsp - #8]",
 962                 src_offset, dst_offset);
 963       break;
 964     case Op_VecD:
 965       st->print("pushq   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
 966                 "popq    [rsp + #%d]",
 967                 src_offset, dst_offset);
 968       break;
 969      case Op_VecX:
 970       st->print("pushq   [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
 971                 "popq    [rsp + #%d]\n\t"
 972                 "pushq   [rsp + #%d]\n\t"
 973                 "popq    [rsp + #%d]",
 974                 src_offset, dst_offset, src_offset+8, dst_offset+8);
 975       break;
 976     case Op_VecY:
 977       st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
 978                 "vmovdqu xmm0, [rsp + #%d]\n\t"
 979                 "vmovdqu [rsp + #%d], xmm0\n\t"
 980                 "vmovdqu xmm0, [rsp - #32]",
 981                 src_offset, dst_offset);
 982       break;
 983     case Op_VecZ:
 984       st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
 985                 "vmovdqu xmm0, [rsp + #%d]\n\t"
 986                 "vmovdqu [rsp + #%d], xmm0\n\t"
 987                 "vmovdqu xmm0, [rsp - #64]",
 988                 src_offset, dst_offset);
 989       break;
 990     default:
 991       ShouldNotReachHere();
 992     }
 993 #endif
 994   }
 995 }
 996 
 997 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
 998                                        PhaseRegAlloc* ra_,
 999                                        bool do_size,
1000                                        outputStream* st) const {
1001   assert(cbuf != NULL || st  != NULL, "sanity");
1002   // Get registers to move
1003   OptoReg::Name src_second = ra_->get_reg_second(in(1));
1004   OptoReg::Name src_first = ra_->get_reg_first(in(1));
1005   OptoReg::Name dst_second = ra_->get_reg_second(this);
1006   OptoReg::Name dst_first = ra_->get_reg_first(this);
1007 
1008   enum RC src_second_rc = rc_class(src_second);
1009   enum RC src_first_rc = rc_class(src_first);
1010   enum RC dst_second_rc = rc_class(dst_second);
1011   enum RC dst_first_rc = rc_class(dst_first);
1012 
1013   assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1014          "must move at least 1 register" );
1015 
1016   if (src_first == dst_first && src_second == dst_second) {
1017     // Self copy, no move
1018     return 0;
1019   }
1020   if (bottom_type()->isa_vect() != NULL) {
1021     uint ireg = ideal_reg();
1022     assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1023     assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
1024     if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1025       // mem -> mem
1026       int src_offset = ra_->reg2offset(src_first);
1027       int dst_offset = ra_->reg2offset(dst_first);
1028       vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1029     } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1030       vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
1031     } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1032       int stack_offset = ra_->reg2offset(dst_first);
1033       vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
1034     } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1035       int stack_offset = ra_->reg2offset(src_first);
1036       vec_spill_helper(cbuf, false, true,  stack_offset, dst_first, ireg, st);
1037     } else {
1038       ShouldNotReachHere();
1039     }
1040     return 0;
1041   }
1042   if (src_first_rc == rc_stack) {
1043     // mem ->


2698       0,
2699       0,
2700       RAX_num,  // Op_RegN
2701       RAX_num,  // Op_RegI
2702       RAX_num,  // Op_RegP
2703       XMM0_num, // Op_RegF
2704       XMM0_num, // Op_RegD
2705       RAX_num   // Op_RegL
2706     };
2707     static const int hi[Op_RegL + 1] = {
2708       0,
2709       0,
2710       OptoReg::Bad, // Op_RegN
2711       OptoReg::Bad, // Op_RegI
2712       RAX_H_num,    // Op_RegP
2713       OptoReg::Bad, // Op_RegF
2714       XMM0b_num,    // Op_RegD
2715       RAX_H_num     // Op_RegL
2716     };
2717     // Excluded flags and vector registers.
2718     assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type");
2719     return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2720   %}
2721 %}
2722 
2723 //----------ATTRIBUTES---------------------------------------------------------
2724 //----------Operand Attributes-------------------------------------------------
2725 op_attrib op_cost(0);        // Required cost attribute
2726 
2727 //----------Instruction Attributes---------------------------------------------
2728 ins_attrib ins_cost(100);       // Required cost attribute
2729 ins_attrib ins_size(8);         // Required size attribute (in bits)
2730 ins_attrib ins_short_branch(0); // Required flag: is this instruction
2731                                 // a non-matching short branch variant
2732                                 // of some long branch?
2733 ins_attrib ins_alignment(1);    // Required alignment attribute (must
2734                                 // be a power of 2) specifies the
2735                                 // alignment that some part of the
2736                                 // instruction (not necessarily the
2737                                 // start) requires.  If > 1, a
2738                                 // compute_padding() function must be


3459 
3460 // Flags register, used as output of FLOATING POINT compare instructions
3461 operand rFlagsRegU()
3462 %{
3463   constraint(ALLOC_IN_RC(int_flags));
3464   match(RegFlags);
3465 
3466   format %{ "RFLAGS_U" %}
3467   interface(REG_INTER);
3468 %}
3469 
3470 operand rFlagsRegUCF() %{
3471   constraint(ALLOC_IN_RC(int_flags));
3472   match(RegFlags);
3473   predicate(false);
3474 
3475   format %{ "RFLAGS_U_CF" %}
3476   interface(REG_INTER);
3477 %}
3478 
3479 operand regF() %{


3480    constraint(ALLOC_IN_RC(float_reg));
3481    match(RegF);
3482 
3483    format %{ %}
3484    interface(REG_INTER);
3485 %}
3486 
3487 operand regD() %{


3488    constraint(ALLOC_IN_RC(double_reg));
3489    match(RegD);
3490 
3491    format %{ %}
3492    interface(REG_INTER);
3493 %}
3494 
3495 // Vectors
3496 operand vecS() %{
3497   constraint(ALLOC_IN_RC(vectors_reg));
3498   match(VecS);
3499 
3500   format %{ %}
3501   interface(REG_INTER);
3502 %}
3503 
3504 operand vecD() %{
3505   constraint(ALLOC_IN_RC(vectord_reg));
3506   match(VecD);
3507 
3508   format %{ %}
3509   interface(REG_INTER);
3510 %}
3511 
3512 operand vecX() %{
3513   constraint(ALLOC_IN_RC(vectorx_reg));
3514   match(VecX);
3515 
3516   format %{ %}
3517   interface(REG_INTER);
3518 %}
3519 
3520 operand vecY() %{
3521   constraint(ALLOC_IN_RC(vectory_reg));
3522   match(VecY);
3523 
3524   format %{ %}
3525   interface(REG_INTER);
3526 %}
3527 
3528 //----------Memory Operands----------------------------------------------------
3529 // Direct Memory Operand
3530 // operand direct(immP addr)
3531 // %{
3532 //   match(addr);
3533 
3534 //   format %{ "[$addr]" %}
3535 //   interface(MEMORY_INTER) %{
3536 //     base(0xFFFFFFFF);
3537 //     index(0x4);
3538 //     scale(0x0);
3539 //     disp($addr);
3540 //   %}
3541 // %}
3542 
3543 // Indirect Memory Operand
3544 operand indirect(any_RegP reg)
3545 %{
3546   constraint(ALLOC_IN_RC(ptr_reg));
3547   match(reg);


< prev index next >