< prev index next >

src/cpu/x86/vm/x86_32.ad

Print this page




  84 // the stack will not have this element so FPR1 == st(0) from the
  85 // oopMap viewpoint. This same weirdness with numbering causes
  86 // instruction encoding to have to play games with the register
  87 // encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation
  88 // where it does flt->flt moves to see an example
  89 //
  90 reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg());
  91 reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next());
  92 reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg());
  93 reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next());
  94 reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg());
  95 reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next());
  96 reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg());
  97 reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next());
  98 reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg());
  99 reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next());
 100 reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
 101 reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
 102 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
 103 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());











 104 
 105 // Specify priority of register selection within phases of register
 106 // allocation.  Highest priority is first.  A useful heuristic is to
 107 // give registers a low priority when they are required by machine
 108 // instructions, like EAX and EDX.  Registers which are used as
 109 // pairs must fall on an even boundary (witness the FPR#L's in this list).
 110 // For the Intel integer registers, the equivalent Long pairs are
 111 // EDX:EAX, EBX:ECX, and EDI:EBP.
 112 alloc_class chunk0( ECX,   EBX,   EBP,   EDI,   EAX,   EDX,   ESI, ESP,
 113                     FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
 114                     FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
 115                     FPR6L, FPR6H, FPR7L, FPR7H );

 116 
 117 
 118 //----------Architecture Description Register Classes--------------------------
 119 // Several register classes are automatically defined based upon information in
 120 // this architecture description.
 121 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
 122 // 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
 123 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
 124 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 125 //
 126 // Class for all registers
 127 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
 128 // Class for general registers
 129 reg_class int_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
 130 // Class for general registers which may be used for implicit null checks on win95
 131 // Also safe for use by tailjump. We don't want to allocate in rbp,
 132 reg_class int_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
 133 // Class of "X" registers
 134 reg_class int_x_reg(EBX, ECX, EDX, EAX);
 135 // Class of registers that can appear in an address with no offset.


 218   return operand;
 219 }
 220 
 221 // Buffer for 128-bits masks used by SSE instructions.
 222 static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
 223 
 224 // Static initialization during VM startup.
 225 static jlong *float_signmask_pool  = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
 226 static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
 227 static jlong *float_signflip_pool  = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
 228 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
 229 
 230 // Offset hacking within calls.
 231 static int pre_call_resets_size() {
 232   int size = 0;
 233   Compile* C = Compile::current();
 234   if (C->in_24_bit_fp_mode()) {
 235     size += 6; // fldcw
 236   }
 237   if (C->max_vector_size() > 16) {

 238     size += 3; // vzeroupper
 239   }

 240   return size;
 241 }
 242 
 243 static int preserve_SP_size() {
 244   return 2;  // op, rm(reg/reg)
 245 }
 246 
 247 // !!!!! Special hack to get all type of calls to specify the byte offset
 248 //       from the start of the call to the point where the return address
 249 //       will point.
 250 int MachCallStaticJavaNode::ret_addr_offset() {
 251   int offset = 5 + pre_call_resets_size();  // 5 bytes from start of call to where return address points
 252   if (_method_handle_invoke)
 253     offset += preserve_SP_size();
 254   return offset;
 255 }
 256 
 257 int MachCallDynamicJavaNode::ret_addr_offset() {
 258   return 10 + pre_call_resets_size();  // 10 bytes from start of call to where return address points
 259 }


 714     emit_opcode  (*cbuf, opcode );
 715     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, relocInfo::none);
 716 #ifndef PRODUCT
 717   } else if( !do_size ) {
 718     if( size != 0 ) st->print("\n\t");
 719     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
 720       if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
 721       else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
 722     } else { // FLD, FST, PUSH, POP
 723       st->print("%s [ESP + #%d]",op_str,offset);
 724     }
 725 #endif
 726   }
 727   int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
 728   return size+3+offset_size;
 729 }
 730 
 731 // Helper for XMM registers.  Extra opcode bits, limited syntax.
 732 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
 733                          int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {






 734   if (cbuf) {
 735     MacroAssembler _masm(cbuf);
 736     if (reg_lo+1 == reg_hi) { // double move?
 737       if (is_load) {
 738         __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
 739       } else {
 740         __ movdbl(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
 741       }
 742     } else {
 743       if (is_load) {
 744         __ movflt(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
 745       } else {
 746         __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
 747       }
 748     }
 749 #ifndef PRODUCT
 750   } else if (!do_size) {
 751     if (size != 0) st->print("\n\t");
 752     if (reg_lo+1 == reg_hi) { // double move?
 753       if (is_load) st->print("%s %s,[ESP + #%d]",
 754                               UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
 755                               Matcher::regName[reg_lo], offset);
 756       else         st->print("MOVSD  [ESP + #%d],%s",
 757                               offset, Matcher::regName[reg_lo]);
 758     } else {
 759       if (is_load) st->print("MOVSS  %s,[ESP + #%d]",
 760                               Matcher::regName[reg_lo], offset);
 761       else         st->print("MOVSS  [ESP + #%d],%s",
 762                               offset, Matcher::regName[reg_lo]);
 763     }
 764 #endif
 765   }
 766   int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);










 767   // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
 768   return size+5+offset_size;
 769 }
 770 
 771 
 772 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 773                             int src_hi, int dst_hi, int size, outputStream* st ) {
 774   if (cbuf) {
 775     MacroAssembler _masm(cbuf);
 776     if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
 777       __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 778                 as_XMMRegister(Matcher::_regEncode[src_lo]));
 779     } else {
 780       __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 781                 as_XMMRegister(Matcher::_regEncode[src_lo]));
 782     }
 783 #ifndef PRODUCT
 784   } else if (!do_size) {
 785     if (size != 0) st->print("\n\t");
 786     if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers
 787       if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
 788         st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 789       } else {
 790         st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 791       }
 792     } else {
 793       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
 794         st->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 795       } else {
 796         st->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 797       }
 798     }
 799 #endif
 800   }
 801   // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
 802   // Only MOVAPS SSE prefix uses 1 byte.
 803   int sz = 4;
 804   if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
 805       UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
 806   return size + sz;
 807 }
 808 
 809 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 810                             int src_hi, int dst_hi, int size, outputStream* st ) {
 811   // 32-bit
 812   if (cbuf) {
 813     MacroAssembler _masm(cbuf);
 814     __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 815              as_Register(Matcher::_regEncode[src_lo]));
 816 #ifndef PRODUCT
 817   } else if (!do_size) {
 818     st->print("movdl   %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
 819 #endif
 820   }
 821   return 4;
 822 }
 823 
 824 
 825 static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 826                                  int src_hi, int dst_hi, int size, outputStream* st ) {
 827   // 32-bit
 828   if (cbuf) {
 829     MacroAssembler _masm(cbuf);
 830     __ movdl(as_Register(Matcher::_regEncode[dst_lo]),
 831              as_XMMRegister(Matcher::_regEncode[src_lo]));
 832 #ifndef PRODUCT
 833   } else if (!do_size) {
 834     st->print("movdl   %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
 835 #endif
 836   }
 837   return 4;
 838 }
 839 
 840 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
 841   if( cbuf ) {
 842     emit_opcode(*cbuf, 0x8B );
 843     emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
 844 #ifndef PRODUCT
 845   } else if( !do_size ) {
 846     if( size != 0 ) st->print("\n\t");
 847     st->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
 848 #endif
 849   }
 850   return size+2;
 851 }
 852 
 853 static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
 854                                  int offset, int size, outputStream* st ) {
 855   if( src_lo != FPR1L_num ) {      // Move value to top of FP stack, if not already there
 856     if( cbuf ) {
 857       emit_opcode( *cbuf, 0xD9 );  // FLD (i.e., push it)


 888                             int stack_offset, int reg, uint ireg, outputStream* st);
 889 
 890 static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_offset,
 891                                      int dst_offset, uint ireg, outputStream* st) {
 892   int calc_size = 0;
 893   int src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
 894   int dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
 895   switch (ireg) {
 896   case Op_VecS:
 897     calc_size = 3+src_offset_size + 3+dst_offset_size;
 898     break;
 899   case Op_VecD:
 900     calc_size = 3+src_offset_size + 3+dst_offset_size;
 901     src_offset += 4;
 902     dst_offset += 4;
 903     src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
 904     dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
 905     calc_size += 3+src_offset_size + 3+dst_offset_size;
 906     break;
 907   case Op_VecX:
 908     calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
 909     break;
 910   case Op_VecY:

 911     calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
 912     break;
 913   default:
 914     ShouldNotReachHere();
 915   }
 916   if (cbuf) {
 917     MacroAssembler _masm(cbuf);
 918     int offset = __ offset();
 919     switch (ireg) {
 920     case Op_VecS:
 921       __ pushl(Address(rsp, src_offset));
 922       __ popl (Address(rsp, dst_offset));
 923       break;
 924     case Op_VecD:
 925       __ pushl(Address(rsp, src_offset));
 926       __ popl (Address(rsp, dst_offset));
 927       __ pushl(Address(rsp, src_offset+4));
 928       __ popl (Address(rsp, dst_offset+4));
 929       break;
 930     case Op_VecX:
 931       __ movdqu(Address(rsp, -16), xmm0);
 932       __ movdqu(xmm0, Address(rsp, src_offset));
 933       __ movdqu(Address(rsp, dst_offset), xmm0);
 934       __ movdqu(xmm0, Address(rsp, -16));
 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     int size = __ offset() - offset;
 946     assert(size == calc_size, "incorrect size calculattion");
 947     return size;
 948 #ifndef PRODUCT
 949   } else if (!do_size) {
 950     switch (ireg) {
 951     case Op_VecS:
 952       st->print("pushl   [rsp + #%d]\t# 32-bit mem-mem spill\n\t"
 953                 "popl    [rsp + #%d]",
 954                 src_offset, dst_offset);
 955       break;
 956     case Op_VecD:
 957       st->print("pushl   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
 958                 "popq    [rsp + #%d]\n\t"
 959                 "pushl   [rsp + #%d]\n\t"
 960                 "popq    [rsp + #%d]",
 961                 src_offset, dst_offset, src_offset+4, dst_offset+4);
 962       break;
 963      case Op_VecX:
 964       st->print("movdqu  [rsp - #16], xmm0\t# 128-bit mem-mem spill\n\t"
 965                 "movdqu  xmm0, [rsp + #%d]\n\t"
 966                 "movdqu  [rsp + #%d], xmm0\n\t"
 967                 "movdqu  xmm0, [rsp - #16]",
 968                 src_offset, dst_offset);
 969       break;
 970     case Op_VecY:
 971       st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
 972                 "vmovdqu xmm0, [rsp + #%d]\n\t"
 973                 "vmovdqu [rsp + #%d], xmm0\n\t"
 974                 "vmovdqu xmm0, [rsp - #32]",
 975                 src_offset, dst_offset);






 976       break;
 977     default:
 978       ShouldNotReachHere();
 979     }
 980 #endif
 981   }
 982   return calc_size;
 983 }
 984 
 985 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
 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), "must move at least 1 register" );
 998 
 999   // Generate spill code!
1000   int size = 0;
1001 
1002   if( src_first == dst_first && src_second == dst_second )
1003     return size;            // Self copy, no move
1004 
1005   if (bottom_type()->isa_vect() != NULL) {
1006     uint ireg = ideal_reg();
1007     assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1008     assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity");
1009     assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
1010     if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1011       // mem -> mem
1012       int src_offset = ra_->reg2offset(src_first);
1013       int dst_offset = ra_->reg2offset(dst_first);
1014       return vec_stack_to_stack_helper(cbuf, do_size, src_offset, dst_offset, ireg, st);
1015     } else if (src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
1016       return vec_mov_helper(cbuf, do_size, src_first, dst_first, src_second, dst_second, ireg, st);
1017     } else if (src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
1018       int stack_offset = ra_->reg2offset(dst_first);
1019       return vec_spill_helper(cbuf, do_size, false, stack_offset, src_first, ireg, st);
1020     } else if (src_first_rc == rc_stack && dst_first_rc == rc_xmm ) {
1021       int stack_offset = ra_->reg2offset(src_first);
1022       return vec_spill_helper(cbuf, do_size, true,  stack_offset, dst_first, ireg, st);
1023     } else {
1024       ShouldNotReachHere();
1025     }
1026   }
1027 
1028   // --------------------------------------
1029   // Check for mem-mem move.  push/pop to move.


3952   predicate( UseSSE < 2 );
3953   constraint(ALLOC_IN_RC(fp_flt_reg));
3954   match(RegF);
3955   match(regFPR1);
3956   format %{ %}
3957   interface(REG_INTER);
3958 %}
3959 
3960 // Float register operands
3961 operand regFPR1(regFPR reg) %{
3962   predicate( UseSSE < 2 );
3963   constraint(ALLOC_IN_RC(fp_flt_reg0));
3964   match(reg);
3965   format %{ "FPR1" %}
3966   interface(REG_INTER);
3967 %}
3968 
3969 // XMM Float register operands
3970 operand regF() %{
3971   predicate( UseSSE>=1 );
3972   constraint(ALLOC_IN_RC(float_reg));
3973   match(RegF);
3974   format %{ %}
3975   interface(REG_INTER);
3976 %}
3977 
3978 // XMM Double register operands
3979 operand regD() %{
3980   predicate( UseSSE>=2 );
3981   constraint(ALLOC_IN_RC(double_reg));
3982   match(RegD);
3983   format %{ %}
3984   interface(REG_INTER);
3985 %}
3986 
































3987 
3988 //----------Memory Operands----------------------------------------------------
3989 // Direct Memory Operand
3990 operand direct(immP addr) %{
3991   match(addr);
3992 
3993   format %{ "[$addr]" %}
3994   interface(MEMORY_INTER) %{
3995     base(0xFFFFFFFF);
3996     index(0x4);
3997     scale(0x0);
3998     disp($addr);
3999   %}
4000 %}
4001 
4002 // Indirect Memory Operand
4003 operand indirect(eRegP reg) %{
4004   constraint(ALLOC_IN_RC(int_reg));
4005   match(reg);
4006 


11122   match(Set dst (ConvL2F src));
11123   effect( KILL cr );
11124   format %{ "PUSH   $src.hi\t# Convert long to single float\n\t"
11125             "PUSH   $src.lo\n\t"
11126             "FILD   ST,[ESP + #0]\n\t"
11127             "ADD    ESP,8\n\t"
11128             "FSTP_S $dst\t# F-round" %}
11129   opcode(0xDF, 0x5);  /* DF /5 */
11130   ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
11131   ins_pipe( pipe_slow );
11132 %}
11133 
11134 instruct convL2I_reg( rRegI dst, eRegL src ) %{
11135   match(Set dst (ConvL2I src));
11136   effect( DEF dst, USE src );
11137   format %{ "MOV    $dst,$src.lo" %}
11138   ins_encode(enc_CopyL_Lo(dst,src));
11139   ins_pipe( ialu_reg_reg );
11140 %}
11141 
11142 
11143 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11144   match(Set dst (MoveF2I src));
11145   effect( DEF dst, USE src );
11146   ins_cost(100);
11147   format %{ "MOV    $dst,$src\t# MoveF2I_stack_reg" %}
11148   ins_encode %{
11149     __ movl($dst$$Register, Address(rsp, $src$$disp));
11150   %}
11151   ins_pipe( ialu_reg_mem );
11152 %}
11153 
11154 instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
11155   predicate(UseSSE==0);
11156   match(Set dst (MoveF2I src));
11157   effect( DEF dst, USE src );
11158 
11159   ins_cost(125);
11160   format %{ "FST_S  $dst,$src\t# MoveF2I_reg_stack" %}
11161   ins_encode( Pop_Mem_Reg_FPR(dst, src) );
11162   ins_pipe( fpu_mem_reg );




  84 // the stack will not have this element so FPR1 == st(0) from the
  85 // oopMap viewpoint. This same weirdness with numbering causes
  86 // instruction encoding to have to play games with the register
  87 // encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation
  88 // where it does flt->flt moves to see an example
  89 //
  90 reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg());
  91 reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next());
  92 reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg());
  93 reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next());
  94 reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg());
  95 reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next());
  96 reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg());
  97 reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next());
  98 reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg());
  99 reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next());
 100 reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
 101 reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
 102 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
 103 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
 104 //
 105 // Empty fill registers, which are never used, but supply alignment to xmm regs
 106 //
 107 reg_def FILL0( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(2));
 108 reg_def FILL1( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(3));
 109 reg_def FILL2( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(4));
 110 reg_def FILL3( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(5));
 111 reg_def FILL4( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(6));
 112 reg_def FILL5( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(7));
 113 reg_def FILL6( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(8));
 114 reg_def FILL7( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(9));
 115 
 116 // Specify priority of register selection within phases of register
 117 // allocation.  Highest priority is first.  A useful heuristic is to
 118 // give registers a low priority when they are required by machine
 119 // instructions, like EAX and EDX.  Registers which are used as
 120 // pairs must fall on an even boundary (witness the FPR#L's in this list).
 121 // For the Intel integer registers, the equivalent Long pairs are
 122 // EDX:EAX, EBX:ECX, and EDI:EBP.
 123 alloc_class chunk0( ECX,   EBX,   EBP,   EDI,   EAX,   EDX,   ESI, ESP,
 124                     FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
 125                     FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
 126                     FPR6L, FPR6H, FPR7L, FPR7H,
 127                     FILL0, FILL1, FILL2, FILL3, FILL4, FILL5, FILL6, FILL7);
 128 
 129 
 130 //----------Architecture Description Register Classes--------------------------
 131 // Several register classes are automatically defined based upon information in
 132 // this architecture description.
 133 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
 134 // 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
 135 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
 136 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 137 //
 138 // Class for all registers
 139 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
 140 // Class for general registers
 141 reg_class int_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
 142 // Class for general registers which may be used for implicit null checks on win95
 143 // Also safe for use by tailjump. We don't want to allocate in rbp,
 144 reg_class int_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
 145 // Class of "X" registers
 146 reg_class int_x_reg(EBX, ECX, EDX, EAX);
 147 // Class of registers that can appear in an address with no offset.


 230   return operand;
 231 }
 232 
 233 // Buffer for 128-bits masks used by SSE instructions.
 234 static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
 235 
 236 // Static initialization during VM startup.
 237 static jlong *float_signmask_pool  = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
 238 static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
 239 static jlong *float_signflip_pool  = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
 240 static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
 241 
 242 // Offset hacking within calls.
 243 static int pre_call_resets_size() {
 244   int size = 0;
 245   Compile* C = Compile::current();
 246   if (C->in_24_bit_fp_mode()) {
 247     size += 6; // fldcw
 248   }
 249   if (C->max_vector_size() > 16) {
 250     if(UseAVX <= 2) {
 251       size += 3; // vzeroupper
 252     }
 253   }
 254   return size;
 255 }
 256 
 257 static int preserve_SP_size() {
 258   return 2;  // op, rm(reg/reg)
 259 }
 260 
 261 // !!!!! Special hack to get all type of calls to specify the byte offset
 262 //       from the start of the call to the point where the return address
 263 //       will point.
 264 int MachCallStaticJavaNode::ret_addr_offset() {
 265   int offset = 5 + pre_call_resets_size();  // 5 bytes from start of call to where return address points
 266   if (_method_handle_invoke)
 267     offset += preserve_SP_size();
 268   return offset;
 269 }
 270 
 271 int MachCallDynamicJavaNode::ret_addr_offset() {
 272   return 10 + pre_call_resets_size();  // 10 bytes from start of call to where return address points
 273 }


 728     emit_opcode  (*cbuf, opcode );
 729     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, relocInfo::none);
 730 #ifndef PRODUCT
 731   } else if( !do_size ) {
 732     if( size != 0 ) st->print("\n\t");
 733     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
 734       if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
 735       else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
 736     } else { // FLD, FST, PUSH, POP
 737       st->print("%s [ESP + #%d]",op_str,offset);
 738     }
 739 #endif
 740   }
 741   int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
 742   return size+3+offset_size;
 743 }
 744 
 745 // Helper for XMM registers.  Extra opcode bits, limited syntax.
 746 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
 747                          int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
 748   int in_size_in_bits = Assembler::EVEX_32bit;
 749   int evex_encoding = 0;
 750   if (reg_lo+1 == reg_hi) {
 751     in_size_in_bits = Assembler::EVEX_64bit;
 752     evex_encoding = Assembler::VEX_W;
 753   }
 754   if (cbuf) {
 755     MacroAssembler _masm(cbuf);
 756     if (reg_lo+1 == reg_hi) { // double move?
 757       if (is_load) {
 758         __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
 759       } else {
 760         __ movdbl(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
 761       }
 762     } else {
 763       if (is_load) {
 764         __ movflt(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset));
 765       } else {
 766         __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo]));
 767       }
 768     }
 769 #ifndef PRODUCT
 770   } else if (!do_size) {
 771     if (size != 0) st->print("\n\t");
 772     if (reg_lo+1 == reg_hi) { // double move?
 773       if (is_load) st->print("%s %s,[ESP + #%d]",
 774                               UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
 775                               Matcher::regName[reg_lo], offset);
 776       else         st->print("MOVSD  [ESP + #%d],%s",
 777                               offset, Matcher::regName[reg_lo]);
 778     } else {
 779       if (is_load) st->print("MOVSS  %s,[ESP + #%d]",
 780                               Matcher::regName[reg_lo], offset);
 781       else         st->print("MOVSS  [ESP + #%d],%s",
 782                               offset, Matcher::regName[reg_lo]);
 783     }
 784 #endif
 785   }
 786   bool is_single_byte = false;
 787   if ((UseAVX > 2) && (offset != 0)) {
 788     is_single_byte = Assembler::query_compressed_disp_byte(offset, true, 0, Assembler::EVEX_T1S, in_size_in_bits, evex_encoding);
 789   }
 790   int offset_size = 0;
 791   if (UseAVX > 2 ) {
 792     offset_size = (offset == 0) ? 0 : ((is_single_byte) ? 1 : 4);
 793   } else {
 794     offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
 795   }
 796   size += (UseAVX > 2) ? 2 : 0; // Need an additional two bytes for EVEX
 797   // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
 798   return size+5+offset_size;
 799 }
 800 
 801 
 802 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 803                             int src_hi, int dst_hi, int size, outputStream* st ) {
 804   if (cbuf) {
 805     MacroAssembler _masm(cbuf);
 806     if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
 807       __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 808                 as_XMMRegister(Matcher::_regEncode[src_lo]));
 809     } else {
 810       __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 811                 as_XMMRegister(Matcher::_regEncode[src_lo]));
 812     }
 813 #ifndef PRODUCT
 814   } else if (!do_size) {
 815     if (size != 0) st->print("\n\t");
 816     if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers
 817       if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
 818         st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 819       } else {
 820         st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 821       }
 822     } else {
 823       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
 824         st->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 825       } else {
 826         st->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
 827       }
 828     }
 829 #endif
 830   }
 831   // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
 832   // Only MOVAPS SSE prefix uses 1 byte.  EVEX uses an additional 2 bytes.
 833   int sz = (UseAVX > 2) ? 6 : 4;
 834   if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
 835       UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
 836   return size + sz;
 837 }
 838 
 839 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 840                             int src_hi, int dst_hi, int size, outputStream* st ) {
 841   // 32-bit
 842   if (cbuf) {
 843     MacroAssembler _masm(cbuf);
 844     __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
 845              as_Register(Matcher::_regEncode[src_lo]));
 846 #ifndef PRODUCT
 847   } else if (!do_size) {
 848     st->print("movdl   %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
 849 #endif
 850   }
 851   return (UseAVX> 2) ? 6 : 4;
 852 }
 853 
 854 
 855 static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
 856                                  int src_hi, int dst_hi, int size, outputStream* st ) {
 857   // 32-bit
 858   if (cbuf) {
 859     MacroAssembler _masm(cbuf);
 860     __ movdl(as_Register(Matcher::_regEncode[dst_lo]),
 861              as_XMMRegister(Matcher::_regEncode[src_lo]));
 862 #ifndef PRODUCT
 863   } else if (!do_size) {
 864     st->print("movdl   %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
 865 #endif
 866   }
 867   return (UseAVX> 2) ? 6 : 4;
 868 }
 869 
 870 static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
 871   if( cbuf ) {
 872     emit_opcode(*cbuf, 0x8B );
 873     emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
 874 #ifndef PRODUCT
 875   } else if( !do_size ) {
 876     if( size != 0 ) st->print("\n\t");
 877     st->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
 878 #endif
 879   }
 880   return size+2;
 881 }
 882 
 883 static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
 884                                  int offset, int size, outputStream* st ) {
 885   if( src_lo != FPR1L_num ) {      // Move value to top of FP stack, if not already there
 886     if( cbuf ) {
 887       emit_opcode( *cbuf, 0xD9 );  // FLD (i.e., push it)


 918                             int stack_offset, int reg, uint ireg, outputStream* st);
 919 
 920 static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_offset,
 921                                      int dst_offset, uint ireg, outputStream* st) {
 922   int calc_size = 0;
 923   int src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
 924   int dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
 925   switch (ireg) {
 926   case Op_VecS:
 927     calc_size = 3+src_offset_size + 3+dst_offset_size;
 928     break;
 929   case Op_VecD:
 930     calc_size = 3+src_offset_size + 3+dst_offset_size;
 931     src_offset += 4;
 932     dst_offset += 4;
 933     src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
 934     dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
 935     calc_size += 3+src_offset_size + 3+dst_offset_size;
 936     break;
 937   case Op_VecX:


 938   case Op_VecY:
 939   case Op_VecZ:
 940     calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
 941     break;
 942   default:
 943     ShouldNotReachHere();
 944   }
 945   if (cbuf) {
 946     MacroAssembler _masm(cbuf);
 947     int offset = __ offset();
 948     switch (ireg) {
 949     case Op_VecS:
 950       __ pushl(Address(rsp, src_offset));
 951       __ popl (Address(rsp, dst_offset));
 952       break;
 953     case Op_VecD:
 954       __ pushl(Address(rsp, src_offset));
 955       __ popl (Address(rsp, dst_offset));
 956       __ pushl(Address(rsp, src_offset+4));
 957       __ popl (Address(rsp, dst_offset+4));
 958       break;
 959     case Op_VecX:
 960       __ movdqu(Address(rsp, -16), xmm0);
 961       __ movdqu(xmm0, Address(rsp, src_offset));
 962       __ movdqu(Address(rsp, dst_offset), xmm0);
 963       __ movdqu(xmm0, Address(rsp, -16));
 964       break;
 965     case Op_VecY:
 966       __ vmovdqu(Address(rsp, -32), xmm0);
 967       __ vmovdqu(xmm0, Address(rsp, src_offset));
 968       __ vmovdqu(Address(rsp, dst_offset), xmm0);
 969       __ vmovdqu(xmm0, Address(rsp, -32));
 970     case Op_VecZ:
 971       __ evmovdqu(Address(rsp, -64), xmm0, 2);
 972       __ evmovdqu(xmm0, Address(rsp, src_offset), 2);
 973       __ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
 974       __ evmovdqu(xmm0, Address(rsp, -64), 2);
 975       break;
 976     default:
 977       ShouldNotReachHere();
 978     }
 979     int size = __ offset() - offset;
 980     assert(size == calc_size, "incorrect size calculattion");
 981     return size;
 982 #ifndef PRODUCT
 983   } else if (!do_size) {
 984     switch (ireg) {
 985     case Op_VecS:
 986       st->print("pushl   [rsp + #%d]\t# 32-bit mem-mem spill\n\t"
 987                 "popl    [rsp + #%d]",
 988                 src_offset, dst_offset);
 989       break;
 990     case Op_VecD:
 991       st->print("pushl   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
 992                 "popq    [rsp + #%d]\n\t"
 993                 "pushl   [rsp + #%d]\n\t"
 994                 "popq    [rsp + #%d]",
 995                 src_offset, dst_offset, src_offset+4, dst_offset+4);
 996       break;
 997      case Op_VecX:
 998       st->print("movdqu  [rsp - #16], xmm0\t# 128-bit mem-mem spill\n\t"
 999                 "movdqu  xmm0, [rsp + #%d]\n\t"
1000                 "movdqu  [rsp + #%d], xmm0\n\t"
1001                 "movdqu  xmm0, [rsp - #16]",
1002                 src_offset, dst_offset);
1003       break;
1004     case Op_VecY:
1005       st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
1006                 "vmovdqu xmm0, [rsp + #%d]\n\t"
1007                 "vmovdqu [rsp + #%d], xmm0\n\t"
1008                 "vmovdqu xmm0, [rsp - #32]",
1009                 src_offset, dst_offset);
1010     case Op_VecZ:
1011       st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
1012                 "vmovdqu xmm0, [rsp + #%d]\n\t"
1013                 "vmovdqu [rsp + #%d], xmm0\n\t"
1014                 "vmovdqu xmm0, [rsp - #64]",
1015                 src_offset, dst_offset);
1016       break;
1017     default:
1018       ShouldNotReachHere();
1019     }
1020 #endif
1021   }
1022   return calc_size;
1023 }
1024 
1025 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
1026   // Get registers to move
1027   OptoReg::Name src_second = ra_->get_reg_second(in(1));
1028   OptoReg::Name src_first = ra_->get_reg_first(in(1));
1029   OptoReg::Name dst_second = ra_->get_reg_second(this );
1030   OptoReg::Name dst_first = ra_->get_reg_first(this );
1031 
1032   enum RC src_second_rc = rc_class(src_second);
1033   enum RC src_first_rc = rc_class(src_first);
1034   enum RC dst_second_rc = rc_class(dst_second);
1035   enum RC dst_first_rc = rc_class(dst_first);
1036 
1037   assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
1038 
1039   // Generate spill code!
1040   int size = 0;
1041 
1042   if( src_first == dst_first && src_second == dst_second )
1043     return size;            // Self copy, no move
1044 
1045   if (bottom_type()->isa_vect() != NULL) {
1046     uint ireg = ideal_reg();
1047     assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1048     assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity");
1049     assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
1050     if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1051       // mem -> mem
1052       int src_offset = ra_->reg2offset(src_first);
1053       int dst_offset = ra_->reg2offset(dst_first);
1054       return vec_stack_to_stack_helper(cbuf, do_size, src_offset, dst_offset, ireg, st);
1055     } else if (src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
1056       return vec_mov_helper(cbuf, do_size, src_first, dst_first, src_second, dst_second, ireg, st);
1057     } else if (src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
1058       int stack_offset = ra_->reg2offset(dst_first);
1059       return vec_spill_helper(cbuf, do_size, false, stack_offset, src_first, ireg, st);
1060     } else if (src_first_rc == rc_stack && dst_first_rc == rc_xmm ) {
1061       int stack_offset = ra_->reg2offset(src_first);
1062       return vec_spill_helper(cbuf, do_size, true,  stack_offset, dst_first, ireg, st);
1063     } else {
1064       ShouldNotReachHere();
1065     }
1066   }
1067 
1068   // --------------------------------------
1069   // Check for mem-mem move.  push/pop to move.


3992   predicate( UseSSE < 2 );
3993   constraint(ALLOC_IN_RC(fp_flt_reg));
3994   match(RegF);
3995   match(regFPR1);
3996   format %{ %}
3997   interface(REG_INTER);
3998 %}
3999 
4000 // Float register operands
4001 operand regFPR1(regFPR reg) %{
4002   predicate( UseSSE < 2 );
4003   constraint(ALLOC_IN_RC(fp_flt_reg0));
4004   match(reg);
4005   format %{ "FPR1" %}
4006   interface(REG_INTER);
4007 %}
4008 
4009 // XMM Float register operands
4010 operand regF() %{
4011   predicate( UseSSE>=1 );
4012   constraint(ALLOC_IN_RC(float_reg_legacy));
4013   match(RegF);
4014   format %{ %}
4015   interface(REG_INTER);
4016 %}
4017 
4018 // XMM Double register operands
4019 operand regD() %{
4020   predicate( UseSSE>=2 );
4021   constraint(ALLOC_IN_RC(double_reg_legacy));
4022   match(RegD);
4023   format %{ %}
4024   interface(REG_INTER);
4025 %}
4026 
4027 // Vectors
4028 operand vecS() %{
4029   constraint(ALLOC_IN_RC(vectors_reg_legacy));
4030   match(VecS);
4031 
4032   format %{ %}
4033   interface(REG_INTER);
4034 %}
4035 
4036 operand vecD() %{
4037   constraint(ALLOC_IN_RC(vectord_reg_legacy));
4038   match(VecD);
4039 
4040   format %{ %}
4041   interface(REG_INTER);
4042 %}
4043 
4044 operand vecX() %{
4045   constraint(ALLOC_IN_RC(vectorx_reg_legacy));
4046   match(VecX);
4047 
4048   format %{ %}
4049   interface(REG_INTER);
4050 %}
4051 
4052 operand vecY() %{
4053   constraint(ALLOC_IN_RC(vectory_reg_legacy));
4054   match(VecY);
4055 
4056   format %{ %}
4057   interface(REG_INTER);
4058 %}
4059 
4060 //----------Memory Operands----------------------------------------------------
4061 // Direct Memory Operand
4062 operand direct(immP addr) %{
4063   match(addr);
4064 
4065   format %{ "[$addr]" %}
4066   interface(MEMORY_INTER) %{
4067     base(0xFFFFFFFF);
4068     index(0x4);
4069     scale(0x0);
4070     disp($addr);
4071   %}
4072 %}
4073 
4074 // Indirect Memory Operand
4075 operand indirect(eRegP reg) %{
4076   constraint(ALLOC_IN_RC(int_reg));
4077   match(reg);
4078 


11194   match(Set dst (ConvL2F src));
11195   effect( KILL cr );
11196   format %{ "PUSH   $src.hi\t# Convert long to single float\n\t"
11197             "PUSH   $src.lo\n\t"
11198             "FILD   ST,[ESP + #0]\n\t"
11199             "ADD    ESP,8\n\t"
11200             "FSTP_S $dst\t# F-round" %}
11201   opcode(0xDF, 0x5);  /* DF /5 */
11202   ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
11203   ins_pipe( pipe_slow );
11204 %}
11205 
11206 instruct convL2I_reg( rRegI dst, eRegL src ) %{
11207   match(Set dst (ConvL2I src));
11208   effect( DEF dst, USE src );
11209   format %{ "MOV    $dst,$src.lo" %}
11210   ins_encode(enc_CopyL_Lo(dst,src));
11211   ins_pipe( ialu_reg_reg );
11212 %}
11213 

11214 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11215   match(Set dst (MoveF2I src));
11216   effect( DEF dst, USE src );
11217   ins_cost(100);
11218   format %{ "MOV    $dst,$src\t# MoveF2I_stack_reg" %}
11219   ins_encode %{
11220     __ movl($dst$$Register, Address(rsp, $src$$disp));
11221   %}
11222   ins_pipe( ialu_reg_mem );
11223 %}
11224 
11225 instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
11226   predicate(UseSSE==0);
11227   match(Set dst (MoveF2I src));
11228   effect( DEF dst, USE src );
11229 
11230   ins_cost(125);
11231   format %{ "FST_S  $dst,$src\t# MoveF2I_reg_stack" %}
11232   ins_encode( Pop_Mem_Reg_FPR(dst, src) );
11233   ins_pipe( fpu_mem_reg );


< prev index next >