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