< prev index next >

src/cpu/x86/vm/x86_32.ad

Print this page




 675   if (framesize >= 128) {
 676     size += 6;
 677   } else {
 678     size += framesize ? 3 : 0;
 679   }
 680   return size;
 681 }
 682 
 683 int MachEpilogNode::reloc() const {
 684   return 0; // a large enough number
 685 }
 686 
 687 const Pipeline * MachEpilogNode::pipeline() const {
 688   return MachNode::pipeline_class();
 689 }
 690 
 691 int MachEpilogNode::safepoint_offset() const { return 0; }
 692 
 693 //=============================================================================
 694 
 695 enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack };
 696 static enum RC rc_class( OptoReg::Name reg ) {
 697 
 698   if( !OptoReg::is_valid(reg)  ) return rc_bad;
 699   if (OptoReg::is_stack(reg)) return rc_stack;
 700 
 701   VMReg r = OptoReg::as_VMReg(reg);
 702   if (r->is_Register()) return rc_int;
 703   if (r->is_FloatRegister()) {
 704     assert(UseSSE < 2, "shouldn't be used in SSE2+ mode");
 705     return rc_float;
 706   }




 707   assert(r->is_XMMRegister(), "must be");
 708   return rc_xmm;
 709 }
 710 
 711 static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
 712                         int opcode, const char *op_str, int size, outputStream* st ) {
 713   if( cbuf ) {
 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   }


 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.


3166   calling_convention %{
3167     // No difference between ingoing/outgoing just pass false
3168     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3169   %}
3170 
3171 
3172   // Body of function which returns an integer array locating
3173   // arguments either in registers or in stack slots.  Passed an array
3174   // of ideal registers called "sig" and a "length" count.  Stack-slot
3175   // offsets are based on outgoing arguments, i.e. a CALLER setting up
3176   // arguments for a CALLEE.  Incoming stack arguments are
3177   // automatically biased by the preserve_stack_slots field above.
3178   c_calling_convention %{
3179     // This is obviously always outgoing
3180     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3181   %}
3182 
3183   // Location of C & interpreter return values
3184   c_return_value %{
3185     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3186     static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num,      EAX_num,      FPR1L_num,    FPR1L_num, EAX_num };
3187     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3188 
3189     // in SSE2+ mode we want to keep the FPU stack clean so pretend
3190     // that C functions return float and double results in XMM0.
3191     if( ideal_reg == Op_RegD && UseSSE>=2 )
3192       return OptoRegPair(XMM0b_num,XMM0_num);
3193     if( ideal_reg == Op_RegF && UseSSE>=2 )
3194       return OptoRegPair(OptoReg::Bad,XMM0_num);
3195 
3196     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3197   %}
3198 
3199   // Location of return values
3200   return_value %{
3201     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3202     static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num,      EAX_num,      FPR1L_num,    FPR1L_num, EAX_num };
3203     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3204     if( ideal_reg == Op_RegD && UseSSE>=2 )
3205       return OptoRegPair(XMM0b_num,XMM0_num);
3206     if( ideal_reg == Op_RegF && UseSSE>=1 )
3207       return OptoRegPair(OptoReg::Bad,XMM0_num);
3208     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3209   %}
3210 
3211 %}
3212 
3213 //----------ATTRIBUTES---------------------------------------------------------
3214 //----------Operand Attributes-------------------------------------------------
3215 op_attrib op_cost(0);        // Required cost attribute
3216 
3217 //----------Instruction Attributes---------------------------------------------
3218 ins_attrib ins_cost(100);       // Required cost attribute
3219 ins_attrib ins_size(8);         // Required size attribute (in bits)
3220 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3221                                 // non-matching short branch variant of some
3222                                                             // long branch?
3223 ins_attrib ins_alignment(1);    // Required alignment attribute (must be a power of 2)


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 );




 675   if (framesize >= 128) {
 676     size += 6;
 677   } else {
 678     size += framesize ? 3 : 0;
 679   }
 680   return size;
 681 }
 682 
 683 int MachEpilogNode::reloc() const {
 684   return 0; // a large enough number
 685 }
 686 
 687 const Pipeline * MachEpilogNode::pipeline() const {
 688   return MachNode::pipeline_class();
 689 }
 690 
 691 int MachEpilogNode::safepoint_offset() const { return 0; }
 692 
 693 //=============================================================================
 694 
 695 enum RC { rc_bad, rc_int, rc_mask, rc_float, rc_xmm, rc_stack };
 696 static enum RC rc_class( OptoReg::Name reg ) {
 697 
 698   if( !OptoReg::is_valid(reg)  ) return rc_bad;
 699   if (OptoReg::is_stack(reg)) return rc_stack;
 700 
 701   VMReg r = OptoReg::as_VMReg(reg);
 702   if (r->is_Register()) return rc_int;
 703   if (r->is_FloatRegister()) {
 704     assert(UseSSE < 2, "shouldn't be used in SSE2+ mode");
 705     return rc_float;
 706   }
 707   if (r->is_KRegister()) {
 708     assert(UseAVX > 2, "must be used in AVX3 mode");
 709     return rc_mask;
 710   }
 711   assert(r->is_XMMRegister(), "must be");
 712   return rc_xmm;
 713 }
 714 
 715 static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
 716                         int opcode, const char *op_str, int size, outputStream* st ) {
 717   if( cbuf ) {
 718     emit_opcode  (*cbuf, opcode );
 719     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, relocInfo::none);
 720 #ifndef PRODUCT
 721   } else if( !do_size ) {
 722     if( size != 0 ) st->print("\n\t");
 723     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
 724       if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
 725       else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
 726     } else { // FLD, FST, PUSH, POP
 727       st->print("%s [ESP + #%d]",op_str,offset);
 728     }
 729 #endif
 730   }


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

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


3180   calling_convention %{
3181     // No difference between ingoing/outgoing just pass false
3182     SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3183   %}
3184 
3185 
3186   // Body of function which returns an integer array locating
3187   // arguments either in registers or in stack slots.  Passed an array
3188   // of ideal registers called "sig" and a "length" count.  Stack-slot
3189   // offsets are based on outgoing arguments, i.e. a CALLER setting up
3190   // arguments for a CALLEE.  Incoming stack arguments are
3191   // automatically biased by the preserve_stack_slots field above.
3192   c_calling_convention %{
3193     // This is obviously always outgoing
3194     (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3195   %}
3196 
3197   // Location of C & interpreter return values
3198   c_return_value %{
3199     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3200     static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num,      EAX_num,      FPR1L_num,    FPR1L_num, 0, EAX_num };
3201     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, 0, EDX_num };
3202 
3203     // in SSE2+ mode we want to keep the FPU stack clean so pretend
3204     // that C functions return float and double results in XMM0.
3205     if( ideal_reg == Op_RegD && UseSSE>=2 )
3206       return OptoRegPair(XMM0b_num,XMM0_num);
3207     if( ideal_reg == Op_RegF && UseSSE>=2 )
3208       return OptoRegPair(OptoReg::Bad,XMM0_num);
3209 
3210     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3211   %}
3212 
3213   // Location of return values
3214   return_value %{
3215     assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3216     static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num,      EAX_num,      FPR1L_num,    FPR1L_num, 0, EAX_num };
3217     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, 0, EDX_num };
3218     if( ideal_reg == Op_RegD && UseSSE>=2 )
3219       return OptoRegPair(XMM0b_num,XMM0_num);
3220     if( ideal_reg == Op_RegF && UseSSE>=1 )
3221       return OptoRegPair(OptoReg::Bad,XMM0_num);
3222     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3223   %}
3224 
3225 %}
3226 
3227 //----------ATTRIBUTES---------------------------------------------------------
3228 //----------Operand Attributes-------------------------------------------------
3229 op_attrib op_cost(0);        // Required cost attribute
3230 
3231 //----------Instruction Attributes---------------------------------------------
3232 ins_attrib ins_cost(100);       // Required cost attribute
3233 ins_attrib ins_size(8);         // Required size attribute (in bits)
3234 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3235                                 // non-matching short branch variant of some
3236                                                             // long branch?
3237 ins_attrib ins_alignment(1);    // Required alignment attribute (must be a power of 2)


3966   predicate( UseSSE < 2 );
3967   constraint(ALLOC_IN_RC(fp_flt_reg));
3968   match(RegF);
3969   match(regFPR1);
3970   format %{ %}
3971   interface(REG_INTER);
3972 %}
3973 
3974 // Float register operands
3975 operand regFPR1(regFPR reg) %{
3976   predicate( UseSSE < 2 );
3977   constraint(ALLOC_IN_RC(fp_flt_reg0));
3978   match(reg);
3979   format %{ "FPR1" %}
3980   interface(REG_INTER);
3981 %}
3982 
3983 // XMM Float register operands
3984 operand regF() %{
3985   predicate( UseSSE>=1 );
3986   constraint(ALLOC_IN_RC(float_reg_legacy));
3987   match(RegF);
3988   format %{ %}
3989   interface(REG_INTER);
3990 %}
3991 
3992 // XMM Double register operands
3993 operand regD() %{
3994   predicate( UseSSE>=2 );
3995   constraint(ALLOC_IN_RC(double_reg_legacy));
3996   match(RegD);
3997   format %{ %}
3998   interface(REG_INTER);
3999 %}
4000 
4001 // Vectors
4002 operand vecS() %{
4003   constraint(ALLOC_IN_RC(vectors_reg_legacy));
4004   match(VecS);
4005 
4006   format %{ %}
4007   interface(REG_INTER);
4008 %}
4009 
4010 operand vecD() %{
4011   constraint(ALLOC_IN_RC(vectord_reg_legacy));
4012   match(VecD);
4013 
4014   format %{ %}
4015   interface(REG_INTER);
4016 %}
4017 
4018 operand vecX() %{
4019   constraint(ALLOC_IN_RC(vectorx_reg_legacy));
4020   match(VecX);
4021 
4022   format %{ %}
4023   interface(REG_INTER);
4024 %}
4025 
4026 operand vecY() %{
4027   constraint(ALLOC_IN_RC(vectory_reg_legacy));
4028   match(VecY);
4029 
4030   format %{ %}
4031   interface(REG_INTER);
4032 %}
4033 
4034 //----------Memory Operands----------------------------------------------------
4035 // Direct Memory Operand
4036 operand direct(immP addr) %{
4037   match(addr);
4038 
4039   format %{ "[$addr]" %}
4040   interface(MEMORY_INTER) %{
4041     base(0xFFFFFFFF);
4042     index(0x4);
4043     scale(0x0);
4044     disp($addr);
4045   %}
4046 %}
4047 
4048 // Indirect Memory Operand
4049 operand indirect(eRegP reg) %{
4050   constraint(ALLOC_IN_RC(int_reg));
4051   match(reg);
4052 


11168   match(Set dst (ConvL2F src));
11169   effect( KILL cr );
11170   format %{ "PUSH   $src.hi\t# Convert long to single float\n\t"
11171             "PUSH   $src.lo\n\t"
11172             "FILD   ST,[ESP + #0]\n\t"
11173             "ADD    ESP,8\n\t"
11174             "FSTP_S $dst\t# F-round" %}
11175   opcode(0xDF, 0x5);  /* DF /5 */
11176   ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
11177   ins_pipe( pipe_slow );
11178 %}
11179 
11180 instruct convL2I_reg( rRegI dst, eRegL src ) %{
11181   match(Set dst (ConvL2I src));
11182   effect( DEF dst, USE src );
11183   format %{ "MOV    $dst,$src.lo" %}
11184   ins_encode(enc_CopyL_Lo(dst,src));
11185   ins_pipe( ialu_reg_reg );
11186 %}
11187 

11188 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11189   match(Set dst (MoveF2I src));
11190   effect( DEF dst, USE src );
11191   ins_cost(100);
11192   format %{ "MOV    $dst,$src\t# MoveF2I_stack_reg" %}
11193   ins_encode %{
11194     __ movl($dst$$Register, Address(rsp, $src$$disp));
11195   %}
11196   ins_pipe( ialu_reg_mem );
11197 %}
11198 
11199 instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
11200   predicate(UseSSE==0);
11201   match(Set dst (MoveF2I src));
11202   effect( DEF dst, USE src );
11203 
11204   ins_cost(125);
11205   format %{ "FST_S  $dst,$src\t# MoveF2I_reg_stack" %}
11206   ins_encode( Pop_Mem_Reg_FPR(dst, src) );
11207   ins_pipe( fpu_mem_reg );


< prev index next >